设计模式之建造者模式

建造者模式

为什么使用及建造者模式

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

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

代码样例

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

整体步骤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可以设置步骤的执行顺序。

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值