JAVA設(shè)計(jì)模式----建造者模式詳解
介紹
建造者模式(Builder Pattern):將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。建造者模式是一種對(duì)象創(chuàng)建型模式。
建造者模式一步一步創(chuàng)建一個(gè)復(fù)雜的對(duì)象,它允許用戶只通過(guò)指定復(fù)雜對(duì)象的類(lèi)型和內(nèi)容就可以構(gòu)建它們,用戶不需要知道內(nèi)部的具體構(gòu)建細(xì)節(jié)。

角色
- Builder(抽象建造者):它為創(chuàng)建一個(gè)產(chǎn)品Product對(duì)象的各個(gè)部件指定抽象接口,在該接口中一般聲明兩類(lèi)方法,一類(lèi)方法是buildPartX(),它們用于創(chuàng)建復(fù)雜對(duì)象的各個(gè)部件;另一類(lèi)方法是getResult(),它們用于返回復(fù)雜對(duì)象。Builder既可以是抽象類(lèi),也可以是接口。
- ConcreteBuilder(具體建造者):它實(shí)現(xiàn)了Builder接口,實(shí)現(xiàn)各個(gè)部件的具體構(gòu)造和裝配方法,定義并明確它所創(chuàng)建的復(fù)雜對(duì)象,也可以提供一個(gè)方法返回創(chuàng)建好的復(fù)雜產(chǎn)品對(duì)象。
- Product(產(chǎn)品角色):它是被構(gòu)建的復(fù)雜對(duì)象,包含多個(gè)組成部件,具體由建造者創(chuàng)建該產(chǎn)品的內(nèi)部表示并定義它的裝配過(guò)程。
- Director(指揮者):指揮者又稱為導(dǎo)演類(lèi),它負(fù)責(zé)安排復(fù)雜對(duì)象的建造次序,指揮者與抽象建造者之間存在關(guān)聯(lián)關(guān)系,可以在其construct()建造方法中調(diào)用建造者對(duì)象的部件構(gòu)造與裝配方法,完成復(fù)雜對(duì)象的建造??蛻舳艘话阒恍枰c指揮者進(jìn)行交互,在客戶端確定具體建造者的類(lèi)型,并實(shí)例化具體建造者對(duì)象(也可以通過(guò)配置文件和反射機(jī)制),然后通過(guò)指揮者類(lèi)的構(gòu)造函數(shù)或者Setter方法將該對(duì)象傳入指揮者類(lèi)中。
在建造者模式的定義中提到了復(fù)雜對(duì)象,那么什么是復(fù)雜對(duì)象?簡(jiǎn)單來(lái)說(shuō),復(fù)雜對(duì)象是指那些包含多個(gè)成員屬性的對(duì)象,這些成員屬性也稱為部件或零件,如汽車(chē)包括方向盤(pán)、發(fā)動(dòng)機(jī)、輪胎等部件,電子郵件包括發(fā)件人、收件人、主題、內(nèi)容、附件等部件
代碼演示
產(chǎn)品角色:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Computer
{
String mouse;
String keyBoard;
String screen;
}
抽象建造者 builder
public abstract class Builder
{
//要建造的產(chǎn)品--子類(lèi)也可以使用,因此是protected
protected Computer computer=new Computer();
//建造的步驟--順序不固定
//方法都是抽象的,具體實(shí)現(xiàn)交給子類(lèi)完成
public abstract Builder buildMouse();
public abstract Builder buildKeyBoard();
public abstract Builder buildScreen();
//創(chuàng)建產(chǎn)品的方法,由當(dāng)前抽象層實(shí)現(xiàn)
public Computer createComputer()
{
return computer;
}
}
具體建造者 DellComputerBuilder,ASUSComputerBuilder,分別建造戴爾電腦和華碩電腦
//鏈?zhǔn)秸{(diào)用
public class DellComputerBuilder extends Builder
{
@Override
public Builder buildMouse()
{
System.out.println("戴爾鼠標(biāo)組裝");
return this;
}
@Override
public Builder buildKeyBoard()
{
System.out.println("戴爾鍵盤(pán)組裝");
return this;
}
@Override
public Builder buildScreen()
{
System.out.println("戴爾屏幕組裝");
return this;
}
}
public class ASUSComputerBuilder extends Builder{
@Override
public Builder buildMouse()
{
System.out.println("華碩鼠標(biāo)組裝");
return this;
}
@Override
public Builder buildKeyBoard()
{
System.out.println("華碩鍵盤(pán)組裝");
return this;
}
@Override
public Builder buildScreen()
{
System.out.println("華碩屏幕組裝");
return this;
}
}
指揮者 ComputerDirector,指揮構(gòu)建過(guò)程
public class ComputerDirector
{
//構(gòu)建電腦的方法
public Computer construct(Builder builder)
{
//構(gòu)建復(fù)雜產(chǎn)品對(duì)象
Computer computer=builder.
buildMouse().
buildKeyBoard().
buildScreen().
createComputer();
return computer;
}
}
客戶端測(cè)試
public class test
{
@Test
public void test()
{
//獲得建造指揮官
ComputerDirector computerDirector=new ComputerDirector();
//創(chuàng)建電腦
computerDirector.construct(new DellComputerBuilder());
computerDirector.construct(new ASUSComputerBuilder());
}
}

通過(guò)反射創(chuàng)建建造者對(duì)象
可以通過(guò)反射機(jī)制和配置文件配合,創(chuàng)建具體建造者對(duì)象
public class test
{
@SneakyThrows//異常拋出throw,一個(gè)簡(jiǎn)單的try...catch寫(xiě)法
@Test
public void test()
{
//獲得建造指揮官
ComputerDirector computerDirector=new ComputerDirector();
//創(chuàng)建電腦
Class<?> dcb = Class.forName("construct.DellComputerBuilder");
computerDirector.construct((Builder) dcb.newInstance());
Class<?> acb = Class.forName("construct.ASUSComputerBuilder");
computerDirector.construct((Builder) acb.newInstance());
}
}
優(yōu)點(diǎn)
在建造者模式中,客戶端不必知道產(chǎn)品內(nèi)部組成的細(xì)節(jié),將產(chǎn)品本身與產(chǎn)品的創(chuàng)建過(guò)程解耦,使得相同的創(chuàng)建過(guò)程可以創(chuàng)建不同的產(chǎn)品對(duì)象。
每一個(gè)具體建造者都相對(duì)獨(dú)立,而與其他的具體建造者無(wú)關(guān),因此可以很方便地替換具體建造者或增加新的具體建造者,用戶使用不同的具體建造者即可得到不同的產(chǎn)品對(duì)象。由于指揮者類(lèi)針對(duì)抽象建造者編程,增加新的具體建造者無(wú)須修改原有類(lèi)庫(kù)的代碼,系統(tǒng)擴(kuò)展方便,符合“開(kāi)閉原則”。
可以更加精細(xì)地控制產(chǎn)品的創(chuàng)建過(guò)程。將復(fù)雜產(chǎn)品的創(chuàng)建步驟分解在不同的方法中,使得創(chuàng)建過(guò)程更加清晰,也更方便使用程序來(lái)控制創(chuàng)建過(guò)程。
缺點(diǎn)
建造者模式所創(chuàng)建的產(chǎn)品一般具有較多的共同點(diǎn),其組成部分相似,如果產(chǎn)品之間的差異性很大,例如很多組成部分都不相同,不適合使用建造者模式,因此其使用范圍受到一定的限制。
如果產(chǎn)品的內(nèi)部變化復(fù)雜,可能會(huì)導(dǎo)致需要定義很多具體建造者類(lèi)來(lái)實(shí)現(xiàn)這種變化,導(dǎo)致系統(tǒng)變得很龐大,增加系統(tǒng)的理解難度和運(yùn)行成本。
適用場(chǎng)景
- 需要生成的產(chǎn)品對(duì)象有復(fù)雜的內(nèi)部結(jié)構(gòu),這些產(chǎn)品對(duì)象通常包含多個(gè)成員屬性。
- 需要生成的產(chǎn)品對(duì)象的屬性相互依賴,需要指定其生成順序。
- 對(duì)象的創(chuàng)建過(guò)程獨(dú)立于創(chuàng)建該對(duì)象的類(lèi)。在建造者模式中通過(guò)引入了指揮者類(lèi),將創(chuàng)建過(guò)程封裝在指揮者類(lèi)中,而不在建造者類(lèi)和客戶類(lèi)中。
- 隔離復(fù)雜對(duì)象的創(chuàng)建和使用,并使得相同的創(chuàng)建過(guò)程可以創(chuàng)建不同的產(chǎn)品。
總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
java實(shí)現(xiàn)批量導(dǎo)入Excel表格數(shù)據(jù)到數(shù)據(jù)庫(kù)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)批量導(dǎo)入Excel表格數(shù)據(jù)到數(shù)據(jù)庫(kù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08
指定springboot的jar運(yùn)行內(nèi)存方式
這篇文章主要介紹了指定springboot的jar運(yùn)行內(nèi)存方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
springboot實(shí)現(xiàn)郵箱驗(yàn)證碼功能
這篇文章主要為大家詳細(xì)介紹了springboot實(shí)現(xiàn)郵箱驗(yàn)證碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02
Mybatis Plus框架項(xiàng)目落地實(shí)踐分析總結(jié)
這篇文章主要為大家介紹了Mybatis Plus框架項(xiàng)目落地實(shí)踐分析總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
使用Spring源碼報(bào)錯(cuò)java:找不到類(lèi) InstrumentationSavingAgent的問(wèn)題
這篇文章主要介紹了使用Spring源碼報(bào)錯(cuò)java:找不到類(lèi) InstrumentationSavingAgent的問(wèn)題,本文給大家分享解決方法,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
jstack配合top命令分析CPU飆高、程序死鎖問(wèn)題
記得前段時(shí)間,同事說(shuō)他們測(cè)試環(huán)境的服務(wù)器cpu使用率一直處于100%,本地又沒(méi)有什么接口調(diào)用,為什么會(huì)這樣?cpu使用率居高不下,自然是有某些線程一直占用著cpu資源,那又如何查看占用cpu較高的線程2021-09-09
java Volatile與Synchronized的區(qū)別
這篇文章主要介紹了java Volatile與Synchronized的區(qū)別,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-12-12
SpringBoot實(shí)現(xiàn)阿里云短信接口對(duì)接的示例代碼
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)阿里云短信接口對(duì)接的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09

