設(shè)計(jì)模式-生成器模式

生成器模式(Builder Pattern)是一種創(chuàng)建型設(shè)計(jì)模式扫倡,用于處理具有復(fù)雜構(gòu)造過程的對(duì)象的創(chuàng)建問題邻寿。

例如污茵,當(dāng)要構(gòu)造一種交互復(fù)雜的產(chǎn)品時(shí)(例如一輛車或者一個(gè)文檔)渠抹,產(chǎn)品的構(gòu)建過程可能需要多個(gè)步驟蝙昙,并且步驟的順序可能不同。此時(shí)梧却,使用生成器模式可以將產(chǎn)品的構(gòu)建過程和產(chǎn)品本身解耦奇颠,可以更靈活地控制產(chǎn)品的構(gòu)建過程,同時(shí)不會(huì)使得構(gòu)造函數(shù)變得過于冗長和復(fù)雜放航。

生成器模式的主要角色包括:

抽象生成器(Builder):定義創(chuàng)建產(chǎn)品的接口烈拒,包括創(chuàng)建產(chǎn)品各個(gè)部分的方法。

具體生成器(ConcreteBuilder):實(shí)現(xiàn)Builder接口广鳍,完成具體的產(chǎn)品構(gòu)建和組裝荆几。

指揮者(Director):負(fù)責(zé)調(diào)用生成器的方法,并指導(dǎo)構(gòu)建過程搜锰,但不涉及具體產(chǎn)品信息伴郁。

產(chǎn)品(Product):表示正在構(gòu)建的復(fù)雜對(duì)象。

以下是一個(gè)簡(jiǎn)單的生成器模式的Java實(shí)現(xiàn)示例:

// Product

public class Car {

? ? private String engine;

? ? private String wheels;

? ? // ... other parts of a car

? ? // ... setters and getters

}

// Builder

public interface CarBuilder {

? ? CarBuilder buildEngine(String engine);

? ? CarBuilder buildWheels(String wheels);

? ? Car build();

}

// ConcreteBuilder

public class CarBuilderImpl implements CarBuilder {

? ? private Car car;

? ? public CarBuilderImpl() {

? ? ? ? this.car = new Car();

? ? }

? ? @Override

? ? public CarBuilder buildEngine(String engine) {

? ? ? ? car.setEngine(engine);

? ? ? ? return this;

? ? }

? ? @Override

? ? public CarBuilder buildWheels(String wheels) {

? ? ? ? car.setWheels(wheels);

? ? ? ? return this;

? ? }

? ? @Override

? ? public Car build() {

? ? ? ? return car;

? ? }

}

// Director

public class CarDirector {

? ? public Car buildSportCar(CarBuilder builder) {

? ? ? ? return builder.buildEngine("Sport engine").buildWheels("Sport wheels").build();

? ? }

? ? public Car buildSUVCar(CarBuilder builder) {

? ? ? ? return builder.buildEngine("SUV engine").buildWheels("SUV wheels").build();

? ? }

}

// Client

public class Client {

? ? public static void main(String[] args) {

? ? ? ? CarBuilder builder = new CarBuilderImpl();

? ? ? ? CarDirector director = new CarDirector();

? ? ? ? Car sportCar = director.buildSportCar(builder);

? ? ? ? Car suvCar = director.buildSUVCar(builder);

? ? ? ? // ... use the car objects

? ? }

}

這個(gè)例子中蛋叼,我們定義了一個(gè)Car類作為需要構(gòu)建的復(fù)雜對(duì)象(Product)焊傅,CarBuilder接口作為抽象生成器(Builder)剂陡,它定義了構(gòu)建Car所需要的方法。CarBuilderImpl類作為具體生成器(ConcreteBuilder)狐胎,它實(shí)現(xiàn)了CarBuilder中定義的方法鸭栖。CarDirector類作為指揮者(Director),它使用具體生成器來構(gòu)建不同類型的Car對(duì)象握巢。

在使用生成器模式時(shí)晕鹊,可以根據(jù)需要省略Director部分,客戶端可以直接使用Builder來創(chuàng)建Product暴浦。

生成器模式提供了一種更好的方法來創(chuàng)建復(fù)雜對(duì)象溅话,使得對(duì)象的創(chuàng)建過程和對(duì)象本身的表示分離開來,使用者不需要知道對(duì)象的內(nèi)部構(gòu)造和組裝過程歌焦,只需要知道需要哪個(gè)生成器就可以得到相應(yīng)的對(duì)象飞几。生成器模式尤其對(duì)于有多個(gè)部分組成且每個(gè)部分都可能不同的對(duì)象創(chuàng)建過程非常有用。



在 Spring 框架中独撇,雖然沒有專門的生成器模式實(shí)現(xiàn)屑墨,但是可以利用 Spring 框架自身的依賴注入(DI)和面向切面編程(AOP)來實(shí)現(xiàn)相似的功能。

以下是一個(gè)示例纷铣,展示了如何在 Spring 中使用生成器模式來構(gòu)建一個(gè)復(fù)雜對(duì)象:

首先卵史,定義一個(gè)包含多個(gè)屬性的目標(biāo)對(duì)象:

public class ComplexObject {

? ? private String property1;

? ? private int property2;

? ? // 其他屬性


? ? // 設(shè)置私有構(gòu)造函數(shù),防止外部直接實(shí)例化該對(duì)象

? ? private ComplexObject() {}


? ? // 提供必要屬性的 getter 和 setter 方法

? ? // ...

}

然后搜立,創(chuàng)建一個(gè)生成器接口來定義生成器的行為:

public interface ComplexObjectBuilder {

? ? ComplexObjectBuilder setProperty1(String property1);

? ? ComplexObjectBuilder setProperty2(int property2);

? ? // 其他設(shè)置屬性的方法


? ? ComplexObject build();

}

接下來以躯,創(chuàng)建一個(gè)實(shí)現(xiàn)生成器接口的類:

public class ComplexObjectBuilderImpl implements ComplexObjectBuilder {

? ? private ComplexObject complexObject;


? ? public ComplexObjectBuilderImpl() {

? ? ? ? complexObject = new ComplexObject();

? ? }


? ? public ComplexObjectBuilder setProperty1(String property1) {

? ? ? ? complexObject.setProperty1(property1);

? ? ? ? return this;

? ? }


? ? public ComplexObjectBuilder setProperty2(int property2) {

? ? ? ? complexObject.setProperty2(property2);

? ? ? ? return this;

? ? }


? ? public ComplexObject build() {

? ? ? ? // 執(zhí)行額外的復(fù)雜構(gòu)建邏輯,如設(shè)置其他屬性等

? ? ? ? return complexObject;

? ? }

}

最后儒拂,可以在 Spring 容器中配置生成器實(shí)例寸潦,并通過依賴注入來使用該生成器:

@Configuration

public class AppConfig {

? ? @Bean

? ? public ComplexObjectBuilder complexObjectBuilder() {

? ? ? ? return new ComplexObjectBuilderImpl();

? ? }


? ? @Bean

? ? public ComplexObject complexObject(ComplexObjectBuilder complexObjectBuilder) {

? ? ? ? return complexObjectBuilder

? ? ? ? ? ? ? ? .setProperty1("value1")

? ? ? ? ? ? ? ? .setProperty2(42)

? ? ? ? ? ? ? ? .build();

? ? }

}

在上面的代碼中,我們通過 ComplexObjectBuilderImpl 實(shí)現(xiàn)了生成器模式的功能社痛,并通過 Spring 的配置類 AppConfig 將 ComplexObjectBuilder 接口和目標(biāo)對(duì)象 ComplexObject 注入到 Spring IoC 容器中见转。

通過以上配置,我們可以在需要使用 ComplexObject 的地方直接注入該對(duì)象蒜哀,而不必手動(dòng)構(gòu)建和設(shè)置屬性斩箫。

這樣,我們就在 Spring 中使用生成器模式構(gòu)建了一個(gè)復(fù)雜對(duì)象撵儿。當(dāng)然乘客,這只是一個(gè)簡(jiǎn)化的示例,實(shí)際應(yīng)用中可能需要更復(fù)雜的生成器實(shí)現(xiàn)和依賴注入配置淀歇。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末易核,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子浪默,更是在濱河造成了極大的恐慌牡直,老刑警劉巖缀匕,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異碰逸,居然都是意外死亡乡小,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門饵史,熙熙樓的掌柜王于貴愁眉苦臉地迎上來满钟,“玉大人,你說我怎么就攤上這事胳喷∨确” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵厌蔽,是天一觀的道長牵辣。 經(jīng)常有香客問我,道長奴饮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任择浊,我火速辦了婚禮戴卜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘琢岩。我一直安慰自己投剥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布担孔。 她就那樣靜靜地躺著江锨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪糕篇。 梳的紋絲不亂的頭發(fā)上啄育,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音拌消,去河邊找鬼挑豌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛墩崩,可吹牛的內(nèi)容都是我干的氓英。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼鹦筹,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼铝阐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起铐拐,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤徘键,失蹤者是張志新(化名)和其女友劉穎练对,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啊鸭,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锹淌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赠制。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赂摆。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖钟些,靈堂內(nèi)的尸體忽然破棺而出烟号,到底是詐尸還是另有隱情,我是刑警寧澤政恍,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布汪拥,位于F島的核電站,受9級(jí)特大地震影響篙耗,放射性物質(zhì)發(fā)生泄漏迫筑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一宗弯、第九天 我趴在偏房一處隱蔽的房頂上張望脯燃。 院中可真熱鬧,春花似錦蒙保、人聲如沸辕棚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽逝嚎。三九已至,卻和暖如春详恼,著一層夾襖步出監(jiān)牢的瞬間补君,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國打工单雾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赚哗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓硅堆,卻偏偏與公主長得像屿储,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子渐逃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容