建造者模式
为什么使用及建造者模式
就以《大话设计模式》中的案例来说吧,中国人做饭,同一个鱼香肉丝,不同的厨师做出来就很容易不同。而且有可能这个缺盐、那个缺醋,怎么么办呢?可以向麦当劳学习。基本上全中国的麦当劳都是一个口味,为什么?因为麦当劳餐饮流程基本上被写死,这个肉炸几分钟,这个饼烤几分钟。。。这样做出来的饭自然味道上都大差不差。因此从麦当劳的经验来看,应当给小厨子定一个做鱼香肉丝的流程,一个步骤接着另一个步骤,至于每个步骤具体怎么做,那肯定要靠小厨子自己以免厨师忘记。
而且这还不够,试想一下我们吃鱼香肉丝的场景,经常有人对老板说多放点辣、少放点辣之类的、把菜炒老点,这也正常嘛,毕竟每个人的口味不一样。但如果只写一个统一的步骤,那么小厨子在做饭的时候就不好控制。怎么办呢?专门找一个人,就叫他厨师长吧,负责指挥小厨子们干活,在分配任务的时候把顾客的特殊需求告诉响应的小厨子。并且,因为小厨子手艺不是太好,每人就先做一个固定口味的鱼香肉丝。
代码样例
我说的比较混乱,结合和具体的代码可能会好点:
整体步骤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可以设置步骤的执行顺序。
目前也是刚刚接触建造者模式,对其理解还比较肤浅,甚至有些地方理解错误。如果有哪里理解不到位的地方,还请指出。收到后必定会在第一时间进行改正,本篇博客也会持续更新,有新的理解会及时补充
本文纯原创,写作不易,如果了帮到您,请点赞、转发、收藏!杜绝抄袭,转载请注明来源!
网友评论