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ì)象的類型和內(nèi)容就可以構(gòu)建它們,用戶不需要知道內(nèi)部的具體構(gòu)建細(xì)節(jié)。

角色
- Builder(抽象建造者):它為創(chuàng)建一個(gè)產(chǎn)品Product對(duì)象的各個(gè)部件指定抽象接口,在該接口中一般聲明兩類方法,一類方法是buildPartX(),它們用于創(chuàng)建復(fù)雜對(duì)象的各個(gè)部件;另一類方法是getResult(),它們用于返回復(fù)雜對(duì)象。Builder既可以是抽象類,也可以是接口。
- 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)演類,它負(fù)責(zé)安排復(fù)雜對(duì)象的建造次序,指揮者與抽象建造者之間存在關(guān)聯(lián)關(guān)系,可以在其construct()建造方法中調(diào)用建造者對(duì)象的部件構(gòu)造與裝配方法,完成復(fù)雜對(duì)象的建造??蛻舳艘话阒恍枰c指揮者進(jìn)行交互,在客戶端確定具體建造者的類型,并實(shí)例化具體建造者對(duì)象(也可以通過(guò)配置文件和反射機(jī)制),然后通過(guò)指揮者類的構(gòu)造函數(shù)或者Setter方法將該對(duì)象傳入指揮者類中。
在建造者模式的定義中提到了復(fù)雜對(duì)象,那么什么是復(fù)雜對(duì)象?簡(jiǎn)單來(lái)說(shuō),復(fù)雜對(duì)象是指那些包含多個(gè)成員屬性的對(duì)象,這些成員屬性也稱為部件或零件,如汽車包括方向盤、發(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)品--子類也可以使用,因此是protected
protected Computer computer=new Computer();
//建造的步驟--順序不固定
//方法都是抽象的,具體實(shí)現(xiàn)交給子類完成
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("戴爾鍵盤組裝");
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("華碩鍵盤組裝");
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寫法
@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ì)象。由于指揮者類針對(duì)抽象建造者編程,增加新的具體建造者無(wú)須修改原有類庫(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)實(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ì)象的類。在建造者模式中通過(guò)引入了指揮者類,將創(chuàng)建過(guò)程封裝在指揮者類中,而不在建造者類和客戶類中。
- 隔離復(fù)雜對(duì)象的創(chuàng)建和使用,并使得相同的創(chuàng)建過(guò)程可以創(chuàng)建不同的產(chǎn)品。
總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
SpringBoot實(shí)現(xiàn)熱部署的三種方式
本文主要介紹了SpringBoot實(shí)現(xiàn)熱部署的三種方式,主要包括配置pom.xml文件,使用插件的執(zhí)行命令mvn spring-boot:run啟動(dòng)項(xiàng),使用springloader本地啟動(dòng)修改jvm參數(shù),使用devtools工具包,感興趣的可以了解一下2023-12-12
mybatis-spring:@MapperScan注解的使用
這篇文章主要介紹了mybatis-spring:@MapperScan注解的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
Java獲取當(dāng)?shù)氐娜粘鋈章鋾r(shí)間代碼分享
這篇文章主要介紹了Java獲取當(dāng)?shù)氐娜粘鋈章鋾r(shí)間代碼分享,國(guó)外猿友寫的一個(gè)類,需要的朋友可以參考下2014-06-06
Java案例實(shí)現(xiàn)不重復(fù)的隨機(jī)數(shù)
這篇文章主要介紹了Java案例實(shí)現(xiàn)不重復(fù)的隨機(jī)數(shù),通過(guò)創(chuàng)建Set集合對(duì)象,可以使用HashSet也可以使用TreeSet,區(qū)別在于TreeSet是排序后的,創(chuàng)建隨機(jī)數(shù)對(duì)象,獲取一個(gè)隨機(jī)數(shù)去重等操作,需要的朋友可以參考一下2022-04-04
SpringSecurity-2.7中跨域問(wèn)題解析
這篇文章主要介紹了SpringSecurity-2.7中跨域問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01
Spring Web MVC框架學(xué)習(xí)之配置Spring Web MVC
這一篇文章講的是Spring Web MVC各部分的配置方法,包括Java代碼配置和XML文件配置以及MVC命名空間的使用方法。2017-03-03
Spring Boot集群管理工具KafkaAdminClient使用方法解析
這篇文章主要介紹了Spring Boot集群管理工具KafkaAdminClient使用方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
SpringBoot日程管理Quartz與定時(shí)任務(wù)Task實(shí)現(xiàn)詳解
定時(shí)任務(wù)是企業(yè)級(jí)開(kāi)發(fā)中必不可少的組成部分,諸如長(zhǎng)周期業(yè)務(wù)數(shù)據(jù)的計(jì)算,例如年度報(bào)表,諸如系統(tǒng)臟數(shù)據(jù)的處理,再比如系統(tǒng)性能監(jiān)控報(bào)告,還有搶購(gòu)類活動(dòng)的商品上架,這些都離不開(kāi)定時(shí)任務(wù)。本節(jié)將介紹兩種不同的定時(shí)任務(wù)技術(shù)2022-09-09

