更新
Builder模式的使用場景
- 相同的方法,不同的執(zhí)行順序,產(chǎn)生不同的事件結(jié)果(示例的場景);
- 多個部件或零件,都可以裝配到一個對象中,但產(chǎn)生的運行結(jié)果又不相同;
- 產(chǎn)品類非常復(fù)雜,或者產(chǎn)品類中的調(diào)用順序不同產(chǎn)生了不同的作用,這個時候使用建造者模式非常適合;
- 當初始化一個對象非常復(fù)雜,如參數(shù)多,很多參數(shù)都具有默認值。
小結(jié)
Builder模式比較常見的實現(xiàn)形式是通過調(diào)用鏈實現(xiàn),這樣使代碼更簡潔、易懂。
優(yōu)點
- 良好的封裝性,使用建造者模式可以使客戶端不必知道產(chǎn)品內(nèi)部組成的細節(jié)。
- 建造者獨立,容易擴展。
缺點
- 會產(chǎn)生多余的Builder對象以及Director對象,消耗內(nèi)存。
理論
定義
百度百科
java23種設(shè)計模式之一,英文叫Builder Pattern。其核心思想是將一個“復(fù)雜對象的構(gòu)建算法”與它的“部件及組裝方式”分離,使得構(gòu)件算法和組裝方式可以獨立應(yīng)對變化;復(fù)用同樣的構(gòu)建算法可以創(chuàng)建不同的表示,不同的構(gòu)建過程可以復(fù)用相同的部件組裝方式。
組成
- 產(chǎn)品(Product):是被構(gòu)建的對象,是包含多個組件的復(fù)雜結(jié)構(gòu)。
- 抽象建造者(Builder):為創(chuàng)建的產(chǎn)品對象規(guī)定抽象接口,一般包括兩類方法,一類是創(chuàng)建組件的方法(以build開頭),一類是返回創(chuàng)建的對象的方法。
- 具體建造者(ConcreteBuilder):實現(xiàn)建造者接口,實現(xiàn)各個部件的具體構(gòu)造和裝配方法。
- 導(dǎo)演者(Director):負責(zé)指揮復(fù)雜對象的構(gòu)建次序。
示例
以我們東北好吃的餃子為例,包括餃子皮,餃子餡,餃子做法,和蘸料;可以做肉餡和素餡的餃子
序號 | 類名 | 角色 | 說明 |
---|---|---|---|
1 | JiaoZi | 產(chǎn)品 Product | 餃子 |
2 | JiaoZiBuilder | 抽象建造者 Builder | 餃子做法流程 |
3 | BuilderDirector | 導(dǎo)演者 Director | 廚師 |
4 | MeatJiaoZiBuilder | 具體建造者 ConcreteBuilder | 肉餡餃子做法 |
5 | VegetableJiaoZiBuilder | 具體建造者 ConcreteBuilder | 素餡餃子做法 |
6 | CustomMain | 客戶端 | 食客(吃貨) |
1.餃子類
public class JiaoZi {
//皮
private String skin;
//餡
private String stuffing;
//做法
private String practice;
//蘸料
private String dip;
public String getSkin() {
return skin;
}
public void setSkin(String skin) {
this.skin = skin;
}
public String getStuffing() {
return stuffing;
}
public void setStuffing(String stuffing) {
this.stuffing = stuffing;
}
public String getPractice() {
return practice;
}
public void setPractice(String practice) {
this.practice = practice;
}
public String getDip() {
return dip;
}
public void setDip(String dip) {
this.dip = dip;
}
@Override
public String toString() {
return "餃子{" +
"皮='" + skin + '\'' +
", 餡='" + stuffing + '\'' +
", 做法='" + practice + '\'' +
", 蘸料='" + dip + '\'' +
'}';
}
}
2.抽象建造者 Builder (餃子做法流程)
public interface JiaoZiBuilder {
void buildSkin();
void buildStuffing();
void buildPractice();
void buildDip();
JiaoZi buildJiaoZi();
}
3.導(dǎo)演者 Director(廚師)
public class BuilderDirector {
public BuilderDirector() {
}
public JiaoZi constructor(JiaoZiBuilder jiaoZiBuilder){
jiaoZiBuilder.buildSkin();
jiaoZiBuilder.buildStuffing();
jiaoZiBuilder.buildPractice();
jiaoZiBuilder.buildDip();
return jiaoZiBuilder.buildJiaoZi();
}
}
4.具體建造者 ConcreteBuilder(肉餡餃子做法)
public class MeatJiaoZiBuilder implements JiaoZiBuilder {
private JiaoZi jz = new JiaoZi();
@Override
public void buildSkin() {
jz.setSkin("白面");
}
@Override
public void buildStuffing() {
jz.setStuffing("豬肉芹菜");
}
@Override
public void buildPractice() {
jz.setPractice("水煮");
}
@Override
public void buildDip() {
jz.setDip("醬油");
}
@Override
public JiaoZi buildJiaoZi() {
return jz;
}
}
5.具體建造者 ConcreteBuilder(素餡餃子做法)
public class VegetableJiaoZiBuilder implements JiaoZiBuilder {
private JiaoZi jz = new JiaoZi();
@Override
public void buildSkin() {
jz.setSkin("白面");
}
@Override
public void buildStuffing() {
jz.setStuffing("酸菜粉條");
}
@Override
public void buildPractice() {
jz.setPractice("清蒸");
}
@Override
public void buildDip() {
jz.setDip("陳醋");
}
@Override
public JiaoZi buildJiaoZi() {
return jz;
}
}
6.客戶端(吃貨)
public class CustomMain {
public static void main(String[] args) {
//豬肉餃子
BuilderDirector director = new BuilderDirector();
JiaoZi meatJiaoZi = director.constructor(new MeatJiaoZiBuilder());
System.out.println(meatJiaoZi);
//酸菜餃子
JiaoZi vegetableJiaoZi = director.constructor(new VegetableJiaoZiBuilder());
System.out.println(vegetableJiaoZi);
}
}