深入理解设计模式-建造者模式(生成器模式)
文章目錄
- 一、什么是建造者模式
- 二、使用場景
- 三、簡單建造者模式
- 四、傳統(tǒng)建造者模式
- 結(jié)尾
一、什么是建造者模式
建造者模式也稱為生成器模式(英文:Builder Pattern),他可以將復(fù)雜對象的建造過程抽象出來,使這個抽象過程的不同實現(xiàn)方法可以構(gòu)造出不同表現(xiàn)的對象。
二、使用場景
當(dāng)一個類的構(gòu)造函數(shù)參數(shù)個數(shù)超過4個,而且這些參數(shù)有些是可選的參數(shù),考慮使用構(gòu)造者模式。
當(dāng)一個類的構(gòu)造函數(shù)參數(shù)超過4個,而且這些參數(shù)有些是可選的時,我們通常有兩種辦法來構(gòu)建它的對象。 例如我們現(xiàn)在有如下一個類計算機類Computer,其中cpu與ram是必填參數(shù),而其他3個是可選參數(shù),那么我們?nèi)绾螛?gòu)造這個類的實例呢,通常有兩種常用的方式:
public class Computer {
private String cpu;//必須
private String ram;//必須
private int usbCount;//可選
private String keyboard;//可選
private String display;//可選
}
常用方式1:折疊構(gòu)造函數(shù)模式(telescoping constructor pattern ),這個我們經(jīng)常用,如下代碼所示
public class Computer {...public Computer(String cpu, String ram) {this(cpu, ram, 0);}public Computer(String cpu, String ram, int usbCount) {this(cpu, ram, usbCount, "羅技鍵盤");}public Computer(String cpu, String ram, int usbCount, String keyboard) {this(cpu, ram, usbCount, keyboard, "三星顯示器");}public Computer(String cpu, String ram, int usbCount, String keyboard, String display) {this.cpu = cpu;this.ram = ram;this.usbCount = usbCount;this.keyboard = keyboard;this.display = display;} }常用方式2:Javabean 模式,如下所示
public class Computer {...public String getCpu() {return cpu;}public void setCpu(String cpu) {this.cpu = cpu;}public String getRam() {return ram;}public void setRam(String ram) {this.ram = ram;}public int getUsbCount() {return usbCount;} ... }那么這兩種方式有什么弊端呢?
第一種主要是使用及閱讀不方便。你可以想象一下,當(dāng)你要調(diào)用一個類的構(gòu)造函數(shù)時,你首先要決定使用哪一個,然后里面又是一堆參數(shù),如果這些參數(shù)的類型很多又都一樣,你還要搞清楚這些參數(shù)的含義,很容易就傳混了。。。那酸爽誰用誰知道。
第二種方式在構(gòu)建過程中對象的狀態(tài)容易發(fā)生變化,造成錯誤。因為那個類中的屬性是分步設(shè)置的,所以就容易出錯。
為了解決這兩個痛點,builder模式就橫空出世了。
三、簡單建造者模式
在Computer 中創(chuàng)建一個靜態(tài)內(nèi)部類 Builder,然后將Computer 中的參數(shù)都復(fù)制到Builder類中。
在Computer中創(chuàng)建一個private的構(gòu)造函數(shù),參數(shù)為Builder類型
在Builder中創(chuàng)建一個public的構(gòu)造函數(shù),參數(shù)為Computer中必填的那些參數(shù),cpu 和ram。
在Builder中創(chuàng)建設(shè)置函數(shù),對Computer中那些可選參數(shù)進行賦值,返回值為Builder類型的實例
在Builder中創(chuàng)建一個build()方法,在其中構(gòu)建Computer的實例并返回
代碼樣例如下:
構(gòu)建者模式是一個非常實用而常見的創(chuàng)建類型的模式(creational design pattern),例如圖片處理框架Glide,網(wǎng)絡(luò)請求框架Retrofit等都使用了此模式。
上面的內(nèi)容是Builder在Java中一種簡化的使用方式,經(jīng)典的Builder 模式與其有一定的不同,下面介紹傳統(tǒng)建造者模式。
四、傳統(tǒng)建造者模式
構(gòu)建者模式UML圖如下所示:
如上圖所示,builder模式有4個角色。
Product: 最終要生成的對象,例如 Computer實例。
Builder: 構(gòu)建者的抽象基類(有時會使用接口代替)。其定義了構(gòu)建Product的抽象步驟,其實體類需要實現(xiàn)這些步驟。其會包含一個用來返回最終產(chǎn)品的方法Product getProduct()。
ConcreteBuilder: Builder的實現(xiàn)類。
Director: 決定如何構(gòu)建最終產(chǎn)品的算法. 其會包含一個負責(zé)組裝的方法void Construct(Builder builder), 在這個方法中通過調(diào)用builder的方法,就可以設(shè)置builder,等設(shè)置完成后,就可以通過builder的 getProduct() 方法獲得最終的產(chǎn)品。
我們接下來將最開始的例子使用傳統(tǒng)方式來實現(xiàn)一遍。
第一步:我們的目標(biāo)Computer類:
public class Computer {private String cpu;//必須private String ram;//必須private int usbCount;//可選private String keyboard;//可選private String display;//可選public Computer(String cpu, String ram) {this.cpu = cpu;this.ram = ram;}public void setUsbCount(int usbCount) {this.usbCount = usbCount;}public void setKeyboard(String keyboard) {this.keyboard = keyboard;}public void setDisplay(String display) {this.display = display;}@Overridepublic String toString() {return "Computer{" +"cpu='" + cpu + '\'' +", ram='" + ram + '\'' +", usbCount=" + usbCount +", keyboard='" + keyboard + '\'' +", display='" + display + '\'' +'}';} }第二步:抽象構(gòu)建者類
public abstract class ComputerBuilder {public abstract void setUsbCount();public abstract void setKeyboard();public abstract void setDisplay();public abstract Computer getComputer(); }第三步:實體構(gòu)建者類,我們可以根據(jù)要構(gòu)建的產(chǎn)品種類產(chǎn)生多了實體構(gòu)建者類,這里我們需要構(gòu)建兩種品牌的電腦,蘋果電腦和聯(lián)想電腦,所以我們生成了兩個實體構(gòu)建者類。
蘋果電腦構(gòu)建者類
public class MacComputerBuilder extends ComputerBuilder {private Computer computer;public MacComputerBuilder(String cpu, String ram) {computer = new Computer(cpu, ram);}@Overridepublic void setUsbCount() {computer.setUsbCount(2);}@Overridepublic void setKeyboard() {computer.setKeyboard("蘋果鍵盤");}@Overridepublic void setDisplay() {computer.setDisplay("蘋果顯示器");}@Overridepublic Computer getComputer() {return computer;} }聯(lián)想電腦構(gòu)建者類
public class LenovoComputerBuilder extends ComputerBuilder {private Computer computer;public LenovoComputerBuilder(String cpu, String ram) {computer=new Computer(cpu,ram);}@Overridepublic void setUsbCount() {computer.setUsbCount(4);}@Overridepublic void setKeyboard() {computer.setKeyboard("聯(lián)想鍵盤");}@Overridepublic void setDisplay() {computer.setDisplay("聯(lián)想顯示器");}@Overridepublic Computer getComputer() {return computer;} }第四步:指導(dǎo)者類(Director)
public class ComputerDirector {public void makeComputer(ComputerBuilder builder){builder.setUsbCount();builder.setDisplay();builder.setKeyboard();} }首先生成一個director (1),然后生成一個目標(biāo)builder (2),接著使用director組裝builder (3),組裝完畢后使用builder創(chuàng)建產(chǎn)品實例 (4)。
public static void main(String[] args) {ComputerDirector director=new ComputerDirector();//1ComputerBuilder builder=new MacComputerBuilder("I5處理器","三星125");//2director.makeComputer(builder);//3Computer macComputer=builder.getComputer();//4System.out.println("mac computer:"+macComputer.toString());ComputerBuilder lenovoBuilder=new LenovoComputerBuilder("I7處理器","海力士222");director.makeComputer(lenovoBuilder);Computer lenovoComputer=lenovoBuilder.getComputer();System.out.println("lenovo computer:"+lenovoComputer.toString()); }可以看到,文章最開始的使用方式是傳統(tǒng)builder模式的變種, 首先其省略了director 這個角色,將構(gòu)建算法交給了client端,其次將builder 寫到了要構(gòu)建的產(chǎn)品類里面,最后采用了鏈?zhǔn)秸{(diào)用。
結(jié)尾
- 感謝大家的耐心閱讀,如有建議請私信或評論留言。
- 如有收獲,勞煩支持,關(guān)注、點贊、評論、收藏均可,博主會經(jīng)常更新,與大家共同進步
總結(jié)
以上是生活随笔為你收集整理的深入理解设计模式-建造者模式(生成器模式)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 双线性映射:零知识证明的引擎
- 下一篇: 高性能 DotNetty Server