建造者模式
- 建造者模式
- 概述
- 結構
- 結果
- 優缺點
- 使用場景
- 將上述案例改為鏈式調用
- 結果
建造者模式
概述
將一個復雜對象的構建與表示分離,使得同樣的構建過程可以創建不同的表示。
- 分離了部件的構建(由Builder來負責)和裝配(由Director負責)。從而可以構建出復雜的對象。這個模式適用于:某個對象的構建過程復雜的情況。
- 由于實現了構建和裝配的解耦。不同的構建器,相同的裝配,也可以做出不同的對象;相同的構建器,不同的裝配順序也可以做出不同的對象。實現了更好的復用。
- 建造者模式可以將部件與其組裝過程分開,一步一步創建一個復雜對象。用戶只需要指定復雜對象的類型就可以獲得該對象,而無需知道內部的構造細節。
結構
建造者(Builder)模式包含如下角色:
- 抽象建造者類(Builder):這個接口規定要實現復雜對象的那些部分的創建,并不涉及具體的部件對象的創建。
- 具體建造者類(ConcreteBuilder):實現Builder接口,完成復雜產品的各個部件的具體創建方法。在構造過程完成后,提供產品的實例。
- 產品類(Product):要創建的復雜對象
- 指揮者類(Director):調用具體建造者來創建復雜對象的各個部分,在指導者中不涉及具體產品的信息,只負責保證對象各個部分完整創建或按某種順序創建。
類圖:
/*** 抽象建造者類*/
public abstract class Builder {// 聲明computer類型的變量,并賦值protected Computer computer = new Computer();public abstract Computer createComputer();public abstract void builderMemory();public abstract void builderHardDrive();public abstract void builderMotherBoard();public abstract void builderPowerSource();public abstract void builderCpu();
}
/*** 電腦類*/
public class Computer {private String memory;private String hardDrive;private String motherBoard;private String powerSource;private String cpu;public String getMemory() {return memory;}public void setMemory(String memory) {this.memory = memory;}public String getHardDrive() {return hardDrive;}public void setHardDrive(String hardDrive) {this.hardDrive = hardDrive;}public String getMotherBoard() {return motherBoard;}public void setMotherBoard(String motherBoard) {this.motherBoard = motherBoard;}public String getPowerSource() {return powerSource;}public void setPowerSource(String powerSource) {this.powerSource = powerSource;}public String getCpu() {return cpu;}public void setCpu(String cpu) {this.cpu = cpu;}@Overridepublic String toString() {return "Computer{" +"memory='" + memory + '\'' +", hardDrive='" + hardDrive + '\'' +", motherBoard='" + motherBoard + '\'' +", powerSource='" + powerSource + '\'' +", cpu='" + cpu + '\'' +'}';}
}
/*** 指揮者類*/
public class Director {// 聲明builder類型的變量private Builder builder;public Director(Builder builder){this.builder =builder;}// 組裝電腦public Computer construct(){builder.builderMotherBoard();builder.builderCpu();builder.builderMemory();builder.builderHardDrive();builder.builderPowerSource();return builder.createComputer();}
}
/*** 聯想電腦構建者 實現抽象構建者類*/
public class LXComputerBuilder extends Builder{@Overridepublic Computer createComputer() {return computer;}@Overridepublic void builderMemory() {computer.setMemory("8G");}@Overridepublic void builderHardDrive() {computer.setMemory("512G");}@Overridepublic void builderMotherBoard() {computer.setMotherBoard("一塊好板");}@Overridepublic void builderPowerSource() {computer.setPowerSource("600w");}@Overridepublic void builderCpu() {computer.setCpu("i5");}
}
/*** 惠普電腦構建者 實現抽象構建者類*/
public class PHComputerBuilder extends Builder{@Overridepublic Computer createComputer() {return computer;}@Overridepublic void builderMemory() {computer.setMemory("16G");}@Overridepublic void builderHardDrive() {computer.setHardDrive("512G");}@Overridepublic void builderMotherBoard() {computer.setMotherBoard("普通的主板");}@Overridepublic void builderPowerSource() {computer.setPowerSource("500w");}@Overridepublic void builderCpu() {computer.setCpu("i7");}
}
public class Test01 {public static void main(String[] args) {// 創建指揮者類,傳入惠普電腦構建者類Director director = new Director(new PHComputerBuilder());// 調用指揮者類的構建方法,構建惠普電腦Computer construct = director.construct();System.out.println(construct.toString());}
}
結果
優缺點
- 優點:
- 建造者模式的封裝性很好。使用建造者模式可以有效的封裝變化,在使用建造者模式的場景中,一般產品類和建造者類是比較穩定的,因此,將主要的業務邏輯封裝在指揮者類中對整體而而言可以取得比較好的穩定性。
- 在建造者模式中,客戶端不必知道產品內部組成的細節,將產品本身與產品的創建過程解耦,使得相同的創建過程可以創建不同的產品對象。
- 可以更加精細的控制產品的創建過程。將復雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰,也方便使用程序來控制創建過程。
- 建造者模式很容易進行擴展。如果由新的需求,通過實現一個新的建造者類就可以完成,基本上不用修改之前的代碼,符合開閉原則。
- 缺點:
- 建造者模式所創建的產品一般具有較多共同點,其組成部分相似,如果產品之間差異很大,則不適用建造者模式,因此使用范圍受到一定的限制。
使用場景
建造者(Builder)模式創建的是復雜對象,其產品的各個部分經常面臨劇烈的變化,但是將他們組合在一起的算法卻相對穩定,所有通常在一下場合使用:
- 創建的對象較復雜,由多個部件構成,各部件面臨復雜變化,但構建順序是相對穩定的
- 創建復雜對象的算法獨立于該對象的組成部分以及它們的裝配方式,即產品的構建過程和最終的表示是獨立的
將上述案例改為鏈式調用
/*** 電腦類*/
public class Computer {private String memory;private String hardDrive;private String motherBoard;private String powerSource;private String cpu;// 構造方法public Computer(Builder builder) {this.cpu = builder.cpu;this.hardDrive = builder.hardDrive;this.motherBoard = builder.motherBoard;this.powerSource = builder.powerSource;this.memory = builder.memory;}// 將創建者聲明為靜態內部類public static final class Builder {private String memory;private String hardDrive;private String motherBoard;private String powerSource;private String cpu;public Builder cpu(String cpu){this.cpu = cpu;return this; // 直接返回 this,即 Builder對象}public Builder powerSource(String powerSource){this.powerSource = powerSource;return this;}public Builder motherBoard(String motherBoard){this.motherBoard = motherBoard;return this;}public Builder hardDrive(String hardDrive){this.hardDrive = hardDrive;return this;}public Builder memory(String memory){this.memory = memory;return this;}// 直接調用Computer類的構造方法,傳入this,即 Builder對象public Computer build(){return new Computer(this);}}@Overridepublic String toString() {return "Computer{" +"memory='" + memory + '\'' +", hardDrive='" + hardDrive + '\'' +", motherBoard='" + motherBoard + '\'' +", powerSource='" + powerSource + '\'' +", cpu='" + cpu + '\'' +'}';}
}
public class Test02 {public static void main(String[] args) {Computer computer = new Computer.Builder().cpu("i9").hardDrive("2T").memory("32G").powerSource("1000w").motherBoard("華碩").build();System.out.println(computer);}
}