深入解析Java的設(shè)計(jì)模式編程中建造者模式的運(yùn)用
定義:將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。
類(lèi)型:創(chuàng)建類(lèi)模式
類(lèi)圖:
四個(gè)要素
- 產(chǎn)品類(lèi):一般是一個(gè)較為復(fù)雜的對(duì)象,也就是說(shuō)創(chuàng)建對(duì)象的過(guò)程比較復(fù)雜,一般會(huì)有比較多的代碼量。在本類(lèi)圖中,產(chǎn)品類(lèi)是一個(gè)具體的類(lèi),而非抽象類(lèi)。實(shí)際編程中,產(chǎn)品類(lèi)可以是由一個(gè)抽象類(lèi)與它的不同實(shí)現(xiàn)組成,也可以是由多個(gè)抽象類(lèi)與他們的實(shí)現(xiàn)組成。
- 抽象建造者:引入抽象建造者的目的,是為了將建造的具體過(guò)程交與它的子類(lèi)來(lái)實(shí)現(xiàn)。這樣更容易擴(kuò)展。一般至少會(huì)有兩個(gè)抽象方法,一個(gè)用來(lái)建造產(chǎn)品,一個(gè)是用來(lái)返回產(chǎn)品。
- 建造者:實(shí)現(xiàn)抽象類(lèi)的所有未實(shí)現(xiàn)的方法,具體來(lái)說(shuō)一般是兩項(xiàng)任務(wù):組建產(chǎn)品;返回組建好的產(chǎn)品。
- 導(dǎo)演類(lèi):負(fù)責(zé)調(diào)用適當(dāng)?shù)慕ㄔ煺邅?lái)組建產(chǎn)品,導(dǎo)演類(lèi)一般不與產(chǎn)品類(lèi)發(fā)生依賴(lài)關(guān)系,與導(dǎo)演類(lèi)直接交互的是建造者類(lèi)。一般來(lái)說(shuō),導(dǎo)演類(lèi)被用來(lái)封裝程序中易變的部分。
代碼實(shí)現(xiàn)
產(chǎn)品的抽象類(lèi):
package Builder; import java.util.ArrayList; public abstract class AbstractProduct { //記錄執(zhí)行順序 private ArrayList<String> part = new ArrayList<String>(); public abstract void doSomething(); public abstract void doOtherthing(); //final,子類(lèi)不可重寫(xiě) final public void executive(){ for(int i=0;i<this.part.size();i++){ String actionName = this.part.get(i); if(actionName.equals("doSomething")){ this.doSomething(); } else if(actionName.equals("doOtherthing")){ this.doOtherthing(); } } } //final,子類(lèi)不可重寫(xiě) final public void setPart(ArrayList<String> part){ this.part = part; } }
產(chǎn)品的實(shí)現(xiàn)類(lèi):
package Builder; public class Product extends AbstractProduct{ //子類(lèi)具體描述步驟 public void doSomething(){ System.out.println("will do something..."); } public void doOtherthing() { System.out.println("Something has done.Otherthing will be done..."); } }
建造者抽象類(lèi):
package Builder; import java.util.ArrayList; public abstract class Builder { //設(shè)置產(chǎn)品的不同部分,以獲得不同的產(chǎn)品 public abstract void setPart(ArrayList<String> part); //建造產(chǎn)品 public abstract Product buildProduct(); }
建造者實(shí)現(xiàn)類(lèi):
package Builder; import java.util.ArrayList; public class ConcreteProduct extends Builder{ private Product product = new Product(); public void setPart(ArrayList<String> part) { this.product.setPart(part); } public Product buildProduct() { return this.product; } }
導(dǎo)演類(lèi):
package Builder; import java.util.ArrayList; //對(duì)不同產(chǎn)品的生產(chǎn)順序再封裝,對(duì)高層屏蔽細(xì)節(jié) public class Director { private ArrayList<String> part = new ArrayList<String>(); private Builder builder = new ConcreteProduct(); public Product getAProduct() { this.part.clear(); this.part.add("doSomething"); this.part.add("doOtherthing"); builder.setPart(part); return builder.buildProduct(); } }
客戶(hù)端:
package Builder; public class Client { public static void main(String[] args) { Director director = new Director(); System.out.println("將產(chǎn)生10個(gè)產(chǎn)品"); for(int i=1;i<11;i++){ System.out.println("第" + i + "個(gè)產(chǎn)品"); director.getAProduct().executive(); System.out.println(); } } }
建造者模式的優(yōu)點(diǎn)
首先,建造者模式的封裝性很好。使用建造者模式可以有效的封裝變化,在使用建造者模式的場(chǎng)景中,一般產(chǎn)品類(lèi)和建造者類(lèi)是比較穩(wěn)定的,因此,將主要的業(yè)務(wù)邏輯封裝在導(dǎo)演類(lèi)中對(duì)整體而言可以取得比較好的穩(wěn)定性。
其次,建造者模式很容易進(jìn)行擴(kuò)展。如果有新的需求,通過(guò)實(shí)現(xiàn)一個(gè)新的建造者類(lèi)就可以完成,基本上不用修改之前已經(jīng)測(cè)試通過(guò)的代碼,因此也就不會(huì)對(duì)原有功能引入風(fēng)險(xiǎn)。
建造者模式與工廠模式的區(qū)別
我們可以看到,建造者模式與工廠模式是極為相似的,總體上,建造者模式僅僅只比工廠模式多了一個(gè)“導(dǎo)演類(lèi)”的角色。在建造者模式的類(lèi)圖中,假如把這個(gè)導(dǎo)演類(lèi)看做是最終調(diào)用的客戶(hù)端,那么圖中剩余的部分就可以看作是一個(gè)簡(jiǎn)單的工廠模式了。
與工廠模式相比,建造者模式一般用來(lái)創(chuàng)建更為復(fù)雜的對(duì)象,因?yàn)閷?duì)象的創(chuàng)建過(guò)程更為復(fù)雜,因此將對(duì)象的創(chuàng)建過(guò)程獨(dú)立出來(lái)組成一個(gè)新的類(lèi)——導(dǎo)演類(lèi)。也就是說(shuō),工廠模式是將對(duì)象的全部創(chuàng)建過(guò)程封裝在工廠類(lèi)中,由工廠類(lèi)向客戶(hù)端提供最終的產(chǎn)品;而建造者模式中,建造者類(lèi)一般只提供產(chǎn)品類(lèi)中各個(gè)組件的建造,而將具體建造過(guò)程交付給導(dǎo)演類(lèi)。由導(dǎo)演類(lèi)負(fù)責(zé)將各個(gè)組件按照特定的規(guī)則組建為產(chǎn)品,然后將組建好的產(chǎn)品交付給客戶(hù)端。
總結(jié)
建造者模式與工廠模式類(lèi)似,他們都是建造者模式,適用的場(chǎng)景也很相似。一般來(lái)說(shuō),如果產(chǎn)品的建造很復(fù)雜,那么請(qǐng)用工廠模式;如果產(chǎn)品的建造更復(fù)雜,那么請(qǐng)用建造者模式。
相關(guān)文章
IDEA插件(BindED)之查看class文件的十六進(jìn)制
這篇文章主要介紹了IDEA插件(BindED)之查看class文件的十六進(jìn)制,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12Java和Ceylon對(duì)象的構(gòu)造和驗(yàn)證
這篇文章主要為大家詳細(xì)介紹了Java和Ceylon對(duì)象的構(gòu)造和驗(yàn)證,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11Java享元設(shè)計(jì)模式優(yōu)化對(duì)象創(chuàng)建提高性能和效率
Java享元設(shè)計(jì)模式通過(guò)共享可重用的對(duì)象,減少了系統(tǒng)中對(duì)象的數(shù)量,優(yōu)化了對(duì)象的創(chuàng)建和管理,提高了性能和效率。它是一種經(jīng)典的設(shè)計(jì)模式,適用于需要處理大量相似對(duì)象的應(yīng)用程序2023-04-04Java必須學(xué)會(huì)的類(lèi)的繼承與多態(tài)
這篇文章主要介紹了Java類(lèi)的繼承與多態(tài)的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下2020-08-08分布式開(kāi)發(fā)醫(yī)療掛號(hào)系統(tǒng)數(shù)據(jù)字典模塊前后端實(shí)現(xiàn)
這篇文章主要為大家介紹了分布式開(kāi)發(fā)醫(yī)療掛號(hào)系統(tǒng)數(shù)據(jù)字典模塊前后端實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04使用springboot 獲取控制器參數(shù)的幾種方法小結(jié)
這篇文章主要介紹了使用springboot 獲取控制器參數(shù)的幾種方法小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12