定義
將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不用的表示。
用戶只需指定需要建造的類型就可以得到它們,建造過程及細節不需要知道。
類型
創建型
適用場景
①、如果一個對象有非常複雜的內部結構(很多屬性)
②、想把複雜對象的創建和使用分離。
優缺點
優點:
①、封裝性好,創建和使用分離。
②、擴展性好、建造類之間獨立、一定程度上解耦。
缺點:
①、產生多餘的Builder對象。
②、產品內部發生變化,建造者都要修改,成本較大。
代碼實現
案例:組裝一臺電腦,需要顯示器、鼠標、鍵盤、CPU、內存條等等。
這裏直接創建一個電腦類。
public class Computer {
/**
* 顯示器
*/
private String computerDisplay;
/**
* 鼠標
*/
private String computerMouse;
/**
* 鍵盤
*/
private String computerKeyBoard;
/**
* CPU
*/
private String computerCPU;
/**
* 電源
*/
private String computerSource;
public Computer(ComputerBuilder computerBuilder) {
this.computerDisplay = computerBuilder.computerDisplay;
this.computerMouse = computerBuilder.computerMouse;
this.computerKeyBoard = computerBuilder.computerKeyBoard;
this.computerCPU = computerBuilder.computerCPU;
this.computerSource = computerBuilder.computerSource;
}
@Override
public String toString() {
return "Computer{" +
"computerDisplay='" + computerDisplay + '\'' +
", computerMouse='" + computerMouse + '\'' +
", computerKeyBoard='" + computerKeyBoard + '\'' +
", computerCPU='" + computerCPU + '\'' +
", computerSource='" + computerSource + '\'' +
'}';
}
/**
* 靜態內部類(建造者)
*/
public static class ComputerBuilder {
private String computerDisplay;
private String computerMouse;
private String computerKeyBoard;
private String computerCPU;
private String computerSource;
public ComputerBuilder builderComputerDisplay(String computerDisplay) {
this.computerDisplay = computerDisplay;
return this;
}
public ComputerBuilder builderComputerMouse(String computerMouse) {
this.computerMouse = computerMouse;
return this;
}
public ComputerBuilder builderComputerKeyBoard(String computerKeyBoard) {
this.computerKeyBoard = computerKeyBoard;
return this;
}
public ComputerBuilder builderComputerCPU(String computerCPU) {
this.computerCPU = computerCPU;
return this;
}
public ComputerBuilder builderComputerSource(String computerSource) {
this.computerSource = computerSource;
return this;
}
/**
* 將當前建造者傳入
*/
public Computer builder() {
return new Computer(this);
}
}
這裏使用了靜態內部類,採用鏈式調用,返回建造者本身。最後寫一個測試方法。
@Test
public void test1() {
Computer computer = new Computer.ComputerBuilder()
.builderComputerDisplay("LG")
.builderComputerMouse("牧馬人")
.builderComputerKeyBoard("羅技")
.builderComputerCPU("酷睿i7")
.builderComputerSource("電源")
.builder();
System.out.println(computer);
}
看測試結果
C:\android\java\jdk1.8\bin\java.exe
Computer{computerDisplay='LG', computerMouse='牧馬人', computerKeyBoard='羅技', computerCPU='酷睿i7', computerSource='電源'}
當然,這裏是按需調用,調用完之後可以鏈式調用。假如我不想買鼠標了,就不用調用builderComputerMouse()這個方法了,或者我只想買一個顯示器,只用調用builderComputerDisplay()這一個方法即可。
相關源碼
1. StringBuilder、StringBuffer中的append
2. guava中的ImmutableSet中的add
3. CacheBuilder
4. Spring中的BeanDefinitionBuilder
5. SqlSessionFactoryBuilder
注意事項
建造者模式和工廠模式比較相近。
①、調用順序。建造者模式更注重於方法的調用順序,而工廠模式注重於創建產品。
②、創建對象的粒度不同。建造者模式可以創建一些複雜的產品,而工廠模式創建出來的都是一樣的產品。
③、關注點不一樣。工廠模式只要把這個對象創建就OK了,而建造者模式不僅要創建這個產品,還要知道這個產品是由哪些部件組成的。