視頻連接:程序員
建造者模式ide
建造者模式也是屬於建立型模型,是23種GOF之一。測試
ui
建造者模式適用於一個複雜的對象的建造,並且在建造的過程當中,客戶端沒必要知道產品內部組成的細節。this
這裏的表示,咱們用一個具體的例子來講明spa
code
視頻
具體建造者(ConcreteBuilder):實現Builder的接口以構造和裝配該產品的各個部件,定義並明確它所建立的表示,並提供一個檢索產品的接口。對象
指揮者(Director):指揮並構造一個使用Builder接口的對象。blog
產品(Product):表示被構造的複雜對象。ConcreteBuilder建立該產品的內部表示並定義它的裝配過程,包含定義組成部件的類,包括將這些部件裝配成最終產品的接口。
咱們這裏有一需求
需求: 定義一個電腦類,電腦有不少屬性,而且實例化電腦類的對象,以及給該對象賦值。
咱們先不用構造者模式來實現一下
public class Computer{ private String cpu; private String gpu; private String memery; private String hd; /* * ................ * */ public String getCpu() { return cpu; } public void setCpu(String cpu) { this.cpu = cpu; } public String getGpu() { return gpu; } public void setGpu(String gpu) { this.gpu = gpu; } public String getMemery() { return memery; } public void setMemery(String memery) { this.memery = memery; } public String getHd() { return hd; } public void setHd(String hd) { this.hd = hd; } @Override public String toString() { return "Computer{" + "cpu='" + cpu + '\'' + ", gpu='" + gpu + '\'' + ", memery='" + memery + '\'' + ", hd='" + hd + '\'' + '}'; } } // 測試 public class BuilderTest { public static void main(String[] args) { Computer computer = new Computer(); computer.setCpu("i5 9300H"); computer.setGpu("gtx1650"); computer.setMemery("16G"); computer.setHd("256ssd + 1T機械"); System.out.println(computer); } } /** * 咱們先不用建造者模式,看看會有什麼問題?? * 1. 客戶端程序,在實例化好產品以後,必須爲該對象的每個屬性賦值,這樣對客戶端程序員來講,太複雜了,須要瞭解compter類的細節 * 2. 違反了迪米特原則(最少知道原則) * 3. 客戶端程序new出來computer對象不能馬上使用,須要設置不少屬性 * * 至關於你去買電腦,商家不是把電腦成品直接給你,而是給你一堆零件,讓你本身組裝 * * 建造者模式與工廠模式的區別: * 工廠模式,都是直接實例化出一個類的對象便可。 * 建造者模式,是在實例化出類的對象以後,還要給該對象每個屬性賦值! */
結果
咱們改進一下代碼
/** * 電腦建造者類,建造者類,必須關聯電腦產品 * 關聯:一個類的對象,做爲另外一個類的對象成員 */ public class ComputerBuilder { private Computer computer = new Computer(); public Computer build(){ computer.setCpu("i7 8750HK"); computer.setGpu("RTX2080"); computer.setMemery("32G"); computer.setHd("512ssd + 2T機械"); return computer; } } //若是不一樣客戶有不一樣需求呢? public class V1Test { public static void main(String[] args) { // 建立一個建造者 ComputerBuilder computerBuilder = new ComputerBuilder(); // 玩遊戲 Computer computer = computerBuilder.build(); System.out.println(computer); // 開發 Computer computer2 = computerBuilder.build(); System.out.println(computer2); // 辦公 Computer computer3 = computerBuilder.build(); System.out.println(computer3); } } /** * 目前這種寫法還不是建造者模式,目前的優勢: * 1. 客戶端程序員須要一個產品時,直接向建造者要便可,建造者封裝了電腦建造的複雜過程 * * 目前缺點: * 1. 封裝的太過了,不管客戶是什麼需求,都是採用最高的配置 * 這至關於你去買電腦,無論你是買來幹嗎的,商家都會給你配置最貴的電腦! * */
結果
這也不符合常理,咱們再改進一下。
建立三個不一樣的建造者
/** * 電腦建造者類,建造者類,必須關聯電腦產品 * 關聯:一個類的對象,做爲另外一個類的對象 */ public class AdvancedComputerBuilder { private Computer computer = new Computer(); public Computer build(){ computer.setCpu("i7 8750HK"); computer.setMemery("32G"); computer.setHd("512ssd + 2T機械"); return computer; } } public class MiddleComputerBuilder { private Computer computer = new Computer(); public Computer build(){ computer.setCpu("i7 7700hq"); computer.setGpu("gtx1060"); computer.setMemery("16G"); computer.setHd("256ssd + 1T機械"); return computer; } } public class LowComputerBuilder { private Computer computer = new Computer(); public Computer build(){ computer.setCpu("i5 7500u"); computer.setGpu("gtx940mx"); computer.setMemery("8G"); computer.setHd("1T機械"); return computer; } } public class V2Test { public static void main(String[] args) { // 玩遊戲 AdvancedComputerBuilder advancedComputerBuilder = new AdvancedComputerBuilder(); Computer computer = advancedComputerBuilder.build(); System.out.println(computer); // 開發 MiddleComputerBuilder middleComputerBuilder = new MiddleComputerBuilder(); Computer computer2 = middleComputerBuilder.build(); System.out.println(computer2); // 辦公 LowComputerBuilder lowComputerBuilder = new LowComputerBuilder(); Computer computer3 = lowComputerBuilder.build(); System.out.println(computer3); } } /** *針對不一樣的需求,咱們須要建立不一樣的建造者,來分別生產不一樣配置的產品 * * 這仍不是建造者模式 * 優勢: * 1. 能夠根據客戶端的不一樣需求,使用不一樣的建造者生產產品 * * 缺點: * 1. 咱們發現多個建造者中的代碼在重複!出現了重複代碼 * 2. 建造過程不穩定,如何在某個建造者建立產品的過程當中,漏掉了某一步,編譯器也不會提示。沒有標準 */
還不行,再改進一下。
咱們將建造電腦的過程抽象出來定義一個接口,之後無論什麼配置的電腦,都是按照這個步驟走,至關於定義了一套規範,將建造過程穩定下來。
public interface ComputerBuilder { void setCpu(); void setGpu(); void setMemery(); void setHd(); Computer build(); } public class AdvancedComputerBuilder implements ComputerBuilder{ private Computer computer = new Computer(); @Override public void setCpu() { computer.setCpu("i7 8750HK"); } @Override public void setGpu() { computer.setGpu("RTX2080"); } @Override public void setMemery() { computer.setMemery("32G"); } @Override public void setHd() { computer.setHd("512ssd + 2T機械"); } public Computer build(){ return computer; } } public class MiddleComputerBuilder implements ComputerBuilder{ private Computer computer = new Computer(); @Override public void setCpu() { computer.setCpu("i7 7700hq"); } @Override public void setGpu() { computer.setGpu("gtx1060"); } @Override public void setMemery() { computer.setMemery("16G"); } @Override public void setHd() { computer.setHd("256ssd + 1T機械"); } public Computer build(){ return computer; } } public class LowComputerBuilder implements ComputerBuilder{ private Computer computer = new Computer(); @Override public void setCpu() { computer.setCpu("i5 7500u"); } @Override public void setGpu() { computer.setGpu("gtx940mx"); } @Override public void setMemery() { computer.setMemery("8G"); } @Override public void setHd() { computer.setHd("1T機械"); } public Computer build(){ return computer; } }
public class V3Test { public static void main(String[] args) { // 玩遊戲 AdvancedComputerBuilder advancedComputerBuilder = new AdvancedComputerBuilder(); advancedComputerBuilder.setCpu(); advancedComputerBuilder.setGpu(); advancedComputerBuilder.setMemery(); advancedComputerBuilder.setHd(); Computer computer = advancedComputerBuilder.build(); System.out.println(computer); // 開發 MiddleComputerBuilder middleComputerBuilder = new MiddleComputerBuilder(); middleComputerBuilder.setCpu(); middleComputerBuilder.setGpu(); middleComputerBuilder.setMemery(); middleComputerBuilder.setHd(); Computer computer2 = middleComputerBuilder.build(); System.out.println(computer2); // 辦公 LowComputerBuilder lowComputerBuilder = new LowComputerBuilder(); lowComputerBuilder.setCpu(); lowComputerBuilder.setGpu(); lowComputerBuilder.setMemery(); lowComputerBuilder.setHd(); Computer computer3 = lowComputerBuilder.build(); System.out.println(computer3); } } /** *建立一個建造者的抽象接口,把製做產品的具體步驟穩定下來。 * 咱們讓建造者類,去實現建造者接口,接口中的方法步驟,類必須都要實現,少一個則會報錯 * * 優勢: * 建造者類中的建造過程是穩定的。不會漏掉某一步!!這樣客戶端想擴展建造者時,也不會漏掉某一步 * * 缺點: * 1. 代碼依然重複 * 2. 如今又變成了客戶端本身配電腦,又違反了迪米特法則。 * (至關於你去買電腦,雖然不用你親自組裝電腦,可是必須「指揮」那個裝機的人,該裝。。該裝什麼。。) */
又變成了客戶端本身配電腦,又違反了迪米特法則!!!
下面是咱們真正的建造者模式了
public class Director { public Computer build(ComputerBuilder cb){ cb.setCpu(); cb.setGpu(); cb.setMemery(); cb.setHd(); return cb.build(); } } public class V4Test { public static void main(String[] args) { AdvancedComputerBuilder advancedComputerBuilder = new AdvancedComputerBuilder(); MiddleComputerBuilder middleComputerBuilder = new MiddleComputerBuilder(); LowComputerBuilder lowComputerBuilder = new LowComputerBuilder(); Director director = new Director(); // 玩遊戲 Computer computer = director.build(advancedComputerBuilder); System.out.println(computer); // 開發 Computer computer2 = director.build(middleComputerBuilder); System.out.println(computer2); // 辦公 Computer computer3 = director.build(lowComputerBuilder); System.out.println(computer3); } } /** *這就是建造者模式 * 優勢: * 1. 建立對象的過程是穩定不變的 * 2. 建立對象的過程只寫了一次,沒有重複代碼(指揮者完成) * 3. 當須要擴展指揮者的時候,不用修改以前的代碼,符合開閉原則 * * * 建造者模式與工廠模式的區別 * 工廠模式只須要一個簡單的new,new出產品便可。 * 建造者更注重,在new出產品以後的,爲產品賦值的過程! */
這就是咱們的建造者模式,顯然它是符合開閉原則的,假如一個客戶須要中高配的電腦,咱們只須要新建一箇中高配電腦的builder,去實現ComputerBuilder接口,再傳入Directer類build就好了,不須要改變以前的代碼。
而一開始說到的表示,就是這這幾個不一樣配置電腦的建造者,LowComputerBuilder,MiddleComputerBuilder和AdvancedComputerBuilder
最後來講下建造者模式與工長模式的區別:
1.工廠模式只須要一個簡單的new,new出產品便可。
2.建造者更注重,在new出產品以後的,爲產品賦值的過程