美文网首页
设计模式之建造者模式

设计模式之建造者模式

作者: OnlyOne2048 | 来源:发表于2020-08-26 21:38 被阅读0次

    建造者模式

    为什么使用及建造者模式

    就以《大话设计模式》中的案例来说吧,中国人做饭,同一个鱼香肉丝,不同的厨师做出来就很容易不同。而且有可能这个缺盐、那个缺醋,怎么么办呢?可以向麦当劳学习。基本上全中国的麦当劳都是一个口味,为什么?因为麦当劳餐饮流程基本上被写死,这个肉炸几分钟,这个饼烤几分钟。。。这样做出来的饭自然味道上都大差不差。因此从麦当劳的经验来看,应当给小厨子定一个做鱼香肉丝的流程,一个步骤接着另一个步骤,至于每个步骤具体怎么做,那肯定要靠小厨子自己以免厨师忘记。

    而且这还不够,试想一下我们吃鱼香肉丝的场景,经常有人对老板说多放点辣、少放点辣之类的、把菜炒老点,这也正常嘛,毕竟每个人的口味不一样。但如果只写一个统一的步骤,那么小厨子在做饭的时候就不好控制。怎么办呢?专门找一个人,就叫他厨师长吧,负责指挥小厨子们干活,在分配任务的时候把顾客的特殊需求告诉响应的小厨子。并且,因为小厨子手艺不是太好,每人就先做一个固定口味的鱼香肉丝。

    代码样例

    我说的比较混乱,结合和具体的代码可能会好点:

    整体步骤Procedure.java

    package builder;
    
    /**
     * @author: OnlyOne
     * @create: 2020-08-26 18:34
     * @description: 做鱼香肉丝的整体步骤,抽象建造者类,强制规定做鱼香肉丝有哪些步骤
     **/
    public abstract class Procedure {
    
        /**
         * @description: 第一步:放油
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: []       
         * @return void
         **/
        public abstract void putOil();
    
        /**
         * @description: 第二部:放盐
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: []       
         * @return void
         **/
        public abstract void putSalt();
    
        /**
         * @description: 第三部:炒菜
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: []       
         * @return void
         **/
        public abstract void hotVegetables();
    
        /**
         * @description: 上菜
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: []
         * @return YuXiangRouSi
         **/
        public abstract YuXiangRouSi Serve();
    }
    
    

    鱼香肉丝:YuXiangRouSi.java

    package builder;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author: OnlyOne
     * @create: 2020-08-26 18:29
     * @description: 产品类,一个产品分为A,B两部分
     **/
    public class YuXiangRouSi {
    
        List<String> steps = new ArrayList<String>();
    
        public void add(String step) {
            steps.add(step);
        }
    
        public void show() {
            System.out.println("这盘菜的制作过程:");
            for (String step :
                    steps) {
                System.out.println(step);
            }
        }
    
    }
    
    

    厨师长:HeadCooker.java

    package builder;
    
    /**
     * @author: OnlyOne
     * @create: 2020-08-26 18:42
     * @description: 指挥者类,厨师长,根据顾客的不同需求做不同版本的鱼香肉丝
     **/
    public class HeadCooker {
    
        /**
         * @description: 厨师长指挥小厨子们做饭
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: [procedure]       
         * @return void
         **/
        public void direct(Procedure procedure) {
            //第一步,放油
            procedure.putOil();
            //第二部,放盐
            procedure.putSalt();
            //第三部,炒菜
            procedure.hotVegetables();
            //上菜
            procedure.Serve();
        }
    }
    
    

    小厨子A:CookerA.java

    package builder;
    
    /**
     * @author: OnlyOne
     * @create: 2020-08-26 18:38
     * @description: 具体建造者类,小厨子A,专门做鱼香肉丝清淡版,少油、少盐、菜生
     **/
    public class CookerA extends Procedure {
    
        private YuXiangRouSi yuXiangRouSi = new YuXiangRouSi();
    
        /**
         * @return void
         * @description: 第一步:放油
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: []
         **/
        @Override
        public void putOil() {
            yuXiangRouSi.add("放入少量的油");
        }
    
        /**
         * @return void
         * @description: 第二部:放盐
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: []
         **/
        @Override
        public void putSalt() {
            yuXiangRouSi.add("放入少量的盐");
        }
    
        /**
         * @return void
         * @description: 第三部:炒菜
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: []
         **/
        @Override
        public void hotVegetables() {
            yuXiangRouSi.add("小火翻炒");
        }
    
        /**
         * @return YuXiangRouSi
         * @description: 上菜
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: []
         **/
        @Override
        public YuXiangRouSi Serve() {
            return yuXiangRouSi;
        }
    }
    
    

    小厨子B:CookerB.java

    package builder;
    
    /**
     * @author: OnlyOne
     * @create: 2020-08-26 18:38
     * @description: 具体建造者类,小厨子B,专门做鱼香肉丝爽辣版,多油、多盐,菜熟
     **/
    public class CookerB extends Procedure {
    
        private YuXiangRouSi yuXiangRouSi = new YuXiangRouSi();
    
        /**
         * @return void
         * @description: 第一步:放油
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: []
         **/
        @Override
        public void putOil() {
            yuXiangRouSi.add("放入大量的油");
        }
    
        /**
         * @return void
         * @description: 第二部:放盐
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: []
         **/
        @Override
        public void putSalt() {
            yuXiangRouSi.add("放入大量的盐");
        }
    
        /**
         * @return void
         * @description: 第三部:炒菜
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: []
         **/
        @Override
        public void hotVegetables() {
            yuXiangRouSi.add("大火翻炒");
        }
    
        /**
         * @return YuXiangRouSi
         * @description: 上菜
         * @author: OnlyOne
         * @create: 2020/8/26
         * @param: []
         **/
        @Override
        public YuXiangRouSi Serve() {
            return yuXiangRouSi;
        }
    
    }
    
    

    顾客:Main.java

    package builder;
    
    /**
     * @author: OnlyOne
     * @create: 2020-08-26 18:43
     * @description: 客户端
     **/
    public class Main {
        public static void main(String[] args) {
            HeadCooker headCooker = new HeadCooker();
            Procedure cookerA = new CookerA();
            Procedure cookerB = new CookerB();
    
            // 顾客点餐了
            System.out.println("顾客一:来一份清淡版的鱼香肉丝");
            // 厨师长指挥
            headCooker.direct(cookerA);
            // 上菜
            YuXiangRouSi yuXiangRouSiA = cookerA.Serve();
            // 查看做饭步骤
            yuXiangRouSiA.show();
    
            System.out.println("**************************************");
    
            System.out.println("顾客二:来一份爽辣版的鱼香肉丝");
            headCooker.direct(cookerB);
            YuXiangRouSi yuXiangRouSiB = cookerB.Serve();
            yuXiangRouSiB.show();
    
        }
    }
    
    

    运行结果:

    image-20200826211119050

    个人思考

    在使用建造者模式的时候,我明显感觉建造者模式与之前学过的一种设计模式很像,即模板方法。

    模板方法是在抽象类中定义步骤,让子类去继承,关键之处在于相同的方法就在抽象类中实现,而不相同的方法,就让其子类各自实现。相对而言比较简单

    建造者模式与,模板方法很想,我认为它是在模板方法的基础上增加了一个Director(指挥者),这个Director可以设置步骤的执行顺序。

    目前也是刚刚接触建造者模式,对其理解还比较肤浅,甚至有些地方理解错误。如果有哪里理解不到位的地方,还请指出。收到后必定会在第一时间进行改正,本篇博客也会持续更新,有新的理解会及时补充

    本文纯原创,写作不易,如果了帮到您,请点赞、转发、收藏!杜绝抄袭,转载请注明来源!

    相关文章

      网友评论

          本文标题:设计模式之建造者模式

          本文链接:https://www.haomeiwen.com/subject/btzfsktx.html