1、什么是建造者模式

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離, 使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。

說人話:將構(gòu)造復(fù)雜對(duì)象的過程和組成對(duì)象的部件解耦。就像攢電腦一樣,不管什么品牌的配件,只要兼容就可以裝上;同樣,一樣的配件,可以有好多組裝的方式。更直接點(diǎn)就是同一個(gè)類,通過內(nèi)部不同屬性狀態(tài)構(gòu)造不同的對(duì)象。

2、建造者模式定義

#yyds干貨盤點(diǎn)#Java設(shè)計(jì)模式之(三)——建造者模式_建造者模式

在建造者模式中,有 4 個(gè)定義:

①、Product(產(chǎn)品類) :我們具體需要生成的類對(duì)象

②、Builder(抽象建造者類):為我們需要生成的類對(duì)象,構(gòu)建不同的模塊屬性,即:公開構(gòu)建產(chǎn)品類的屬性,隱藏產(chǎn)品類的其他功能。

③、ConcreteBuilder(具體建造者類):實(shí)現(xiàn)抽象類定義的所有方法,并返回一個(gè)組建好的對(duì)象。

④、Director(導(dǎo)演類):確定構(gòu)建我們的類對(duì)象具體有哪些模塊屬性,在實(shí)際應(yīng)用中可以不需要這個(gè)角色,直接通過client處理。

3、實(shí)例

比如我們?nèi)ベI車,一般同一輛車會(huì)有多個(gè)版本,根據(jù)配置不一樣,分為經(jīng)典版、舒適版、豪華版等,比如經(jīng)典版是手動(dòng)擋手動(dòng)座椅,舒適版是自動(dòng)擋全景天窗等。

public class Car {
// 車名稱
private String name;
// 自動(dòng)擋
private String automaticCatch;
// 手動(dòng)擋
private String manualTransmission;
// 全景天窗
private String panoramicSunroof;
// 自動(dòng)座椅
private String automaticSeat;
// 手動(dòng)座椅
private String manualSeat;
// 倒車影像
private String reversingImage;
//省略get/set方法
}

3.1 普通實(shí)現(xiàn)

public class GeneralTest {
public Car getCarInstance(String carName){
Car car = new Car();
if("經(jīng)典版".equals(carName)){
car.setName("經(jīng)典版");
car.setManualTransmission("手動(dòng)擋");
}else if("舒適版".equals(carName)){
car.setName("舒適版");
car.setAutomaticCatch("自動(dòng)擋");
car.setManualSeat("手動(dòng)座椅");
}else if("豪華版".equals(carName)){
car.setName("豪華版");
car.setAutomaticCatch("自動(dòng)擋");
car.setAutomaticSeat("自動(dòng)座椅");
car.setReversingImage("倒車影像");
car.setPanoramicSunroof("全景天窗");
}else{
throw new IllegalArgumentException("carName is error: carName="+carName);
}
return car;
}
}

注意,并不是說高版本汽車一定具有低版本所有配置,比如舒適版配置是手動(dòng)座椅,豪華版是自動(dòng)座椅,而且不同版本之間配置有交叉。

從上面可以看出,根據(jù)汽車類型,我們可以創(chuàng)建相應(yīng)配置的汽車,但其實(shí)汽車的配置是有很多的,種類一旦多了,上面的代碼就會(huì)顯得很臃腫,也不好維護(hù),于是我們用建造者模式來重構(gòu)。

3.2 建造者模式實(shí)現(xiàn)

①、創(chuàng)建抽象建造者類

public abstract class CarBuilder {
public abstract Car buildClassic();
public abstract Car buildComfortable();
public abstract Car buildLuxury();
}

②、創(chuàng)建具體建造者類。對(duì)抽象建造者類的抽象方法進(jìn)行實(shí)現(xiàn)賦值,達(dá)到我們所需要的結(jié)果。

public class CarConcreteBuilder extends CarBuilder{
@Override
public Car buildClassic() {
Car car = new Car();
car.setName("經(jīng)典版");
car.setManualTransmission("手動(dòng)擋");
return car;
}
@Override
public Car buildComfortable() {
Car car = new Car();
car.setName("舒適版");
car.setAutomaticCatch("自動(dòng)擋");
car.setManualSeat("手動(dòng)座椅");
return car;
}
@Override
public Car buildLuxury() {
Car car = new Car();
car.setName("豪華版");
car.setAutomaticCatch("自動(dòng)擋");
car.setAutomaticSeat("自動(dòng)座椅");
car.setReversingImage("倒車影像");
car.setPanoramicSunroof("全景天窗");
return car;
}
}

③、創(chuàng)建我們的導(dǎo)演類,指導(dǎo)我們?cè)趺慈?chuàng)建對(duì)象

public class CarDirector {
private CarBuilder carBuilder;
public CarDirector(CarBuilder carBuilder){
this.carBuilder = carBuilder;
}
public Car classicConstruct(){
return carBuilder.buildClassic();
}
public Car comfortableConstruct(){
return carBuilder.buildComfortable();
}
public Car luxuryConstruct(){
return carBuilder.buildLuxury();
}
}

④、測(cè)試

public class BuilderTest {
public static void main(String[] args) {
CarBuilder carBuilder = new CarConcreteBuilder();
CarDirector carDirector = new CarDirector(carBuilder);
Car classicCar = carDirector.classicConstruct();
System.out.println(classicCar);
Car comfortableCar = carDirector.comfortableConstruct();
System.out.println(comfortableCar);
}
}

另外,對(duì)于不同配置之間有互斥關(guān)系,比如有了手動(dòng)擋,就不可能有自動(dòng)擋,屬性之間的關(guān)系我們也可以在具體建造者類 CarConcreteBuilder 進(jìn)行設(shè)置。

4、與工廠模式區(qū)別

前面我們介紹工廠模式時(shí)說了由工廠類來負(fù)責(zé)創(chuàng)建對(duì)象,而建造者模式也是讓具體建造者類負(fù)責(zé)創(chuàng)建對(duì)象,那這兩者有什么區(qū)別呢?

實(shí)際上工廠模式是用來創(chuàng)建不同但是相關(guān)類型的對(duì)象(繼承同一父類或者接口的一組子類),由給定的參數(shù)來決定創(chuàng)建哪種類型的對(duì)象。而建造者模式是用來創(chuàng)建一種類型的復(fù)雜對(duì)象,通過設(shè)置不同的可選參數(shù),“定制化”地創(chuàng)建不同的對(duì)象。

有這樣一個(gè)例子可以形象的解釋:

顧客走進(jìn)一家餐館點(diǎn)餐,我們利用工廠模式,根據(jù)用戶不同的選擇,來制作不同的食物,比如披薩、漢堡、沙拉。對(duì)于披薩來說,用戶又有各種配料可以定制,比如奶酪、西紅柿、起司,我們通過建造者模式根據(jù)用戶選擇的不同配料來制作披薩。

5、建造者模式優(yōu)點(diǎn)

①、封裝性

使用建造者模式可以使客戶端不必知道產(chǎn)品內(nèi)部組成的細(xì)節(jié), 如例子中我們就不需要關(guān)心每一種版本汽車內(nèi)部是如何實(shí)現(xiàn)的, 產(chǎn)生的對(duì)象類型就是Car。

②、建造者獨(dú)立,容易擴(kuò)展

其實(shí)對(duì)于上面例子中的 CarConcreteBuilder 類,有三個(gè)方法,分別構(gòu)造經(jīng)典版、舒適版、豪華版汽車,每個(gè)方法內(nèi)部是不受影響的,或者我們還可以直接把這一個(gè)類拆成三個(gè)類。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/124952.html

相關(guān)文章

  • #yyds干貨盤點(diǎn)#Java設(shè)計(jì)模式(四)——原型模式

    摘要:如果一個(gè)對(duì)象的初始化需要很多其他對(duì)象的數(shù)據(jù)準(zhǔn)備或其他資源的繁瑣計(jì)算,那么可以使用原型模式。當(dāng)需要一個(gè)對(duì)象的大量公共信息,少量字段進(jìn)行個(gè)性化設(shè)置的時(shí)候,也可以使用原型模式拷貝出現(xiàn)有對(duì)象的副本進(jìn)行加工處理。 1、什么是原型模式Specify the kinds of objects to create using a prot...

    番茄西紅柿 評(píng)論0 收藏2637
  • #yyds干貨盤點(diǎn)# 常用軟件框架,總有一個(gè)用的上

    摘要:一界面框架是微軟在其最新桌面操作系統(tǒng)中使用的圖形用戶界面。干貨盤點(diǎn)二服務(wù)在寫后臺(tái)代碼的過程中,經(jīng)常會(huì)遇到要寫一些多帶帶的服務(wù)。這個(gè)傳統(tǒng)的控件開發(fā)起來很不方面,使用也不友好。發(fā)現(xiàn)有用的,這個(gè)第三方的框架,集成的很好,用起來也方便。一、Fluent Ribbon界面框架Fluent/Ribbon是微軟在其最新桌面操作系統(tǒng)Windows 7中使用的圖形用戶界面。 Windows平臺(tái)的進(jìn)化,伴隨著系...

    番茄西紅柿 評(píng)論0 收藏2637
  • #yyds干貨盤點(diǎn)#設(shè)計(jì)模式【單例模式

    摘要:枚舉推薦優(yōu)點(diǎn)懶加載,線程安全,效率高,大牛推薦作者推薦總結(jié)關(guān)于單例模式的實(shí)現(xiàn)方式,首推的就是枚舉,其次是懶漢模式雙重檢查,最后是靜態(tài)內(nèi)部類 作者:湯圓個(gè)人博客:javalover.cc前言有時(shí)候我們的類并不需要很多個(gè)實(shí)例,在程序運(yùn)行期間,可能只需要一個(gè)實(shí)例就夠了,多了反而會(huì)出現(xiàn)數(shù)據(jù)不一致的問題;這時(shí)候我們就可以...

    sourcenode 評(píng)論0 收藏0
  • #yyds干貨盤點(diǎn)#RedisPub/Sub

    摘要:如下圖,客戶端訂閱頻道干貨盤點(diǎn)之持久化如下圖,當(dāng)消息發(fā)送到客戶端訂閱的頻道時(shí),這個(gè)消息就會(huì)被訂閱的所有未故障的客戶端接接收到干貨盤點(diǎn)之持久化實(shí)例演示演示的發(fā)布訂閱,我們需要開啟多個(gè)客戶端,訂閱頻道。 1、簡(jiǎn)介李子捌把話說在前頭,如果你是面試或者為了了解知識(shí)來學(xué)習(xí)這一知識(shí)點(diǎn),我覺得是有必要的;但是如果你是作為公司的技術(shù)負(fù)責(zé)人...

    番茄西紅柿 評(píng)論0 收藏2637

發(fā)表評(píng)論

0條評(píng)論