設計模式-建造者模式(Builder)
阿新 • • 發佈:2018-11-24
建造者模式(Builder)
- 定義 : 將一個複雜物件的構建與它的表示分離, 是的同樣的構建過程可以建立不同的表示
- 使用者只需指定需要建造的型別就可以得到它們, 建造過程及細節不需要知道
- 型別 : 建立型設計模式
適用場景
- 一個物件有非常複雜的內部結構
- 想把複雜物件的建立和使用分離
優點
- 封裝性好, 建立和使用分離
- 擴充套件性好, 建造類之間獨立, 一定程度上解耦
缺點
- 產生多餘的Builder物件
- 產品內部發生變化, 建造者都要修改, 成本較大
模式角色
-
Builder : 為建立一個Product物件的各個部件指定抽象介面
-
ConcreteBuilder : Builder的實現類
- 實現Builder的介面以構造和裝配該產品的各個部件
- 定義並明確它所建立的表示
- 提供一個檢索產品的介面
-
Director : 構造一個使用Builder介面的物件
-
Product : 被構造的物件
- 表示被構造的複雜物件。ConcreteBuilder 建立該產品的內部表示並定義它的裝配過程
- 包含定義組成部件的類,包括將這些部件裝配成最終產品的介面
程式碼演示
場景: 組裝一臺電腦, 場景中各個類對應的角色如下 :
- Person,組裝電腦的人, 對應Director
- ComputerBuilder, 對應ConcreteBuilder
- IComputerBuilder介面, 對應模式中的Builder
- Computer, 對應Product
版本一
UML類圖
IComputerBuilder構造者介面, 對應模式中Builder
/**
* Builder介面
* 可以使用介面或者抽象類
* @author 七夜雪
* @create 2018-11-22 16:53
*/
public interface IComputerBuilder {
public void buildCpu(String cpu);
public void buildMemory(String memory);
public void buildMainboard(String mainboard);
public void buildDisk(String disk);
public Computer build();
}
ComputerBuilder構造者實現, 對應模式中ConcreteBuilder角色
/**
* builder模式中的builder
* @author 七夜雪
* 2018/11/14 13:51
*/
public class ComputerBuilder implements IComputerBuilder{
private Computer computer = new Computer();
@Override
public Computer build() {
return this.computer;
}
@Override
public void buildCpu(String cpu){
computer.setCpu(cpu);
}
@Override
public void buildMemory(String memory){
computer.setMemory(memory);
}
@Override
public void buildMainboard(String mainboard){
computer.setMainboard(mainboard);
}
@Override
public void buildDisk(String disk){
computer.setDisk(disk);
}
}
Computer電腦類, 對應模式中Product角色
/**
* 電腦類,Builder模式中的Product
*
* @author 七夜雪
* 2018/11/14 13:48
*/
public class Computer {
private String cpu;
private String memory;
private String mainboard;
private String disk;
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setMemory(String memory) {
this.memory = memory;
}
public void setMainboard(String mainboard) {
this.mainboard = mainboard;
}
public void setDisk(String disk) {
this.disk = disk;
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", memory='" + memory + '\'' +
", mainboard='" + mainboard + '\'' +
", disk='" + disk + '\'' +
'}';
}
}
Person類, 對應模式中的Director角色
/**
* builder模式中的Director
* @author 七夜雪
* 2018/11/14 15:23
*/
public class Person {
private ComputerBuilder builder;
public Person(ComputerBuilder builder) {
this.builder = builder;
}
public Computer excuteBuilder(String cpu, String memory, String disk, String mainboard){
builder.buildCpu(cpu);
builder.buildMemory(memory);
builder.buildDisk(disk);
builder.buildMainboard(mainboard);
return builder.build();
}
}
測試類, 對應模式中的Client角色
/**
* builder模式測試類
* @author 七夜雪
* 2018/11/14 13:56
*/
public class Client {
public static void main(String[] args) {
ComputerBuilder builder = new ComputerBuilder();
Person director = new Person(builder);
Computer computer = director.excuteBuilder("酷睿I7", "金士頓 DDR4 16G", "三星512G SSD", "華碩X99");
System.out.println(computer);
}
}
版本二
版本一種, 如果product存在很多屬性, 在執行director的excuteBuilder方法時要傳入很多引數, 容易出現錯誤, 而且如果有些屬性不需要的話, 也必須要傳一個預設值, 所以更通用的一種寫法, 就是講Product和Builder寫在一起, Builder作為Product類的內部類, 同時採用鏈式程式設計方式, 可以選擇構造部分屬性, 對於不需要的屬性則不需要進行構造
UML 類圖
程式碼如下:
/**
* 電腦類,Builder模式中的Product
*
* @author 七夜雪
* 2018/11/14 13:48
*/
public class Computer {
public Computer(ComputerBuilder computerBuilder) {
this.cpu = computerBuilder.cpu;
this.memory = computerBuilder.memory;
this.mainboard = computerBuilder.mainboard;
this.disk = computerBuilder.disk;
}
private String cpu;
private String memory;
private String mainboard;
private String disk;
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setMemory(String memory) {
this.memory = memory;
}
public void setMainboard(String mainboard) {
this.mainboard = mainboard;
}
public void setDisk(String disk) {
this.disk = disk;
}
public static class ComputerBuilder {
private String cpu;
private String memory;
private String mainboard;
private String disk;
public ComputerBuilder buildCPU(String cpu) {
this.cpu = cpu;
return this;
}
public ComputerBuilder buildMemory(String memory){
this.memory = memory;
return this;
}
public ComputerBuilder buildMainboard(String mainboard){
this.mainboard = mainboard;
return this;
}
public ComputerBuilder buildDisk(String disk){
this.disk = disk;
return this;
}
public Computer build(){
return new Computer(this);
}
}
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", memory='" + memory + '\'' +
", mainboard='" + mainboard + '\'' +
", disk='" + disk + '\'' +
'}';
}
}
/**
* Builder第二版測試類
*
* @author 七夜雪
* @create 2018-11-22 17:17
*/
public class ClientV2 {
public static void main(String[] args) {
Computer.ComputerBuilder builder = new Computer.ComputerBuilder();
Computer computer = builder.buildCPU("酷睿I9-9900K")
.buildMemory("海盜船 DDR4 64G")
.buildMainboard("華碩Z390")
.buildDisk("金士頓 1T SSD").build();
System.out.println(computer);
}
}
本文參考:
慕課網<java設計模式精講 Debug 方式+記憶體分析>課程
四人幫<設計模式>