建造者模式
為什么使用及建造者模式
就以《大話設(shè)計(jì)模式》中的案例來說吧豪嚎,中國(guó)人做飯搔驼,同一個(gè)魚香肉絲,不同的廚師做出來就很容易不同侈询。而且有可能這個(gè)缺鹽舌涨、那個(gè)缺醋,怎么么辦呢扔字?可以向麥當(dāng)勞學(xué)習(xí)囊嘉∥录迹基本上全中國(guó)的麥當(dāng)勞都是一個(gè)口味,為什么扭粱?因?yàn)辂湲?dāng)勞餐飲流程基本上被寫死舵鳞,這個(gè)肉炸幾分鐘,這個(gè)餅烤幾分鐘焊刹。系任。。這樣做出來的飯自然味道上都大差不差虐块。因此從麥當(dāng)勞的經(jīng)驗(yàn)來看俩滥,應(yīng)當(dāng)給小廚子定一個(gè)做魚香肉絲的流程,一個(gè)步驟接著另一個(gè)步驟贺奠,至于每個(gè)步驟具體怎么做霜旧,那肯定要靠小廚子自己以免廚師忘記。
而且這還不夠儡率,試想一下我們吃魚香肉絲的場(chǎng)景挂据,經(jīng)常有人對(duì)老板說多放點(diǎn)辣、少放點(diǎn)辣之類的儿普、把菜炒老點(diǎn)崎逃,這也正常嘛,畢竟每個(gè)人的口味不一樣眉孩。但如果只寫一個(gè)統(tǒng)一的步驟个绍,那么小廚子在做飯的時(shí)候就不好控制。怎么辦呢浪汪?專門找一個(gè)人巴柿,就叫他廚師長(zhǎng)吧,負(fù)責(zé)指揮小廚子們干活死遭,在分配任務(wù)的時(shí)候把顧客的特殊需求告訴響應(yīng)的小廚子广恢。并且,因?yàn)樾N子手藝不是太好呀潭,每人就先做一個(gè)固定口味的魚香肉絲钉迷。
代碼樣例
我說的比較混亂,結(jié)合和具體的代碼可能會(huì)好點(diǎn):
整體步驟Procedure.java
package builder;
/**
* @author: OnlyOne
* @create: 2020-08-26 18:34
* @description: 做魚香肉絲的整體步驟钠署,抽象建造者類篷牌,強(qiáng)制規(guī)定做魚香肉絲有哪些步驟
**/
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: 產(chǎn)品類,一個(gè)產(chǎn)品分為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);
}
}
}
廚師長(zhǎng):HeadCooker.java
package builder;
/**
* @author: OnlyOne
* @create: 2020-08-26 18:42
* @description: 指揮者類踏幻,廚師長(zhǎng)枷颊,根據(jù)顧客的不同需求做不同版本的魚香肉絲
**/
public class HeadCooker {
/**
* @description: 廚師長(zhǎng)指揮小廚子們做飯
* @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();
// 顧客點(diǎn)餐了
System.out.println("顧客一:來一份清淡版的魚香肉絲");
// 廚師長(zhǎng)指揮
headCooker.direct(cookerA);
// 上菜
YuXiangRouSi yuXiangRouSiA = cookerA.Serve();
// 查看做飯步驟
yuXiangRouSiA.show();
System.out.println("**************************************");
System.out.println("顧客二:來一份爽辣版的魚香肉絲");
headCooker.direct(cookerB);
YuXiangRouSi yuXiangRouSiB = cookerB.Serve();
yuXiangRouSiB.show();
}
}
運(yùn)行結(jié)果:
個(gè)人思考
在使用建造者模式的時(shí)候,我明顯感覺建造者模式與之前學(xué)過的一種設(shè)計(jì)模式很像淮悼,即模板方法咐低。
模板方法是在抽象類中定義步驟,讓子類去繼承袜腥,關(guān)鍵之處在于相同的方法就在抽象類中實(shí)現(xiàn)见擦,而不相同的方法,就讓其子類各自實(shí)現(xiàn)羹令。相對(duì)而言比較簡(jiǎn)單
建造者模式與鲤屡,模板方法很想,我認(rèn)為它是在模板方法的基礎(chǔ)上增加了一個(gè)Director(指揮者)福侈,這個(gè)Director可以設(shè)置步驟的執(zhí)行順序酒来。
目前也是剛剛接觸建造者模式,對(duì)其理解還比較膚淺肪凛,甚至有些地方理解錯(cuò)誤役首。如果有哪里理解不到位的地方,還請(qǐng)指出显拜。收到后必定會(huì)在第一時(shí)間進(jìn)行改正,本篇博客也會(huì)持續(xù)更新爹袁,有新的理解會(huì)及時(shí)補(bǔ)充
本文純?cè)瓌?chuàng)远荠,寫作不易,如果了幫到您失息,請(qǐng)點(diǎn)贊譬淳、轉(zhuǎn)發(fā)、收藏盹兢!杜絕抄襲邻梆,轉(zhuǎn)載請(qǐng)注明來源!