建造者模式(Builder Pattern):將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。建造者模式是一種對象建立型模式。git
建造者模式一步一步建立一個複雜的對象,它容許用戶只經過指定複雜對象的類型和內容就能夠構建它們,用戶不須要知道內部的具體構建細節。建造者模式結構如圖所示:編程
在建造者模式結構圖中包含以下幾個角色:設計模式
Productide
public class Product { private String partA; private String partB; private String partC; public String getPartA() { return partA; } public void setPartA(String partA) { this.partA = partA; } public String getPartB() { return partB; } public void setPartB(String partB) { this.partB = partB; } public String getPartC() { return partC; } public void setPartC(String partC) { this.partC = partC; } @Override public String toString() { return "Product{" + "partA='" + partA + '\'' + ", partB='" + partB + '\'' + ", partC='" + partC + '\'' + '}'; } }
Builder函數
public abstract class Builder { protected Product product = new Product(); public abstract void buildPartA(); public abstract void buildPartB(); public abstract void buildPartC(); public Product getResult() { return product; } }
ConcreteBuilderui
public class ConcreteBuilder extends Builder { @Override public void buildPartA() { product.setPartA("hahaA"); } @Override public void buildPartB() { product.setPartB("hahaB"); } @Override public void buildPartC() { product.setPartC("hahaC"); } }
Directorthis
public class Director { private Builder builder; public Director(Builder builder) { this.builder = builder; } public Product construct() { builder.buildPartA(); builder.buildPartB(); builder.buildPartC(); return builder.getResult(); } }
Test設計
public class Test { public static void main(String[] args) { Builder builder = new ConcreteBuilder(); Director director = new Director(builder); Product product = director.construct(); System.out.println(product); } } //Product{partA='hahaA', partB='hahaB', partC='hahaC'}
在建造者模式中,客戶端只需實例化指揮者類,指揮者類針對抽象建造者編程,客戶端根據須要傳入具體的建造者類型(可根據配置文件得到),指揮者將指導具體建造者一步一步構造一個完整的產品(逐步調用具體建造者的buildX()方法),相同的構造過程能夠建立徹底不一樣的產品。在遊戲角色實例中,若是須要更換角色,只須要修改配置文件,更換具體角色建造者類便可;若是須要增長新角色,能夠增長一個新的具體角色建造者類做爲抽象角色建造者的子類,再修改配置文件便可,原有代碼無須修改,徹底符合「開閉原則」。code
1 省略Director,直接將Director
中的construct
方法放入Builer
中
public abstract class Builder { protected Product product = new Product(); public abstract void buildPartA(); public abstract void buildPartB(); public abstract void buildPartC(); public Product createProduct() { return product; } public Product construct() { this.buildPartA(); this.buildPartB(); this.buildPartC(); return product; } } ... Builder builder = new ConcreteBuilder(); Product product=builder.construct(); ...
2 添加鉤子方法來控制是否對某個buildX()進行調用
抽象類中給一個默認的鉤子方法
public abstract class Builder { protected Product product = new Product(); public abstract void buildPartA(); public abstract void buildPartB(); public abstract void buildPartC(); public Product createProduct() { return product; } //鉤子方法 public boolean isCNeed(){ return false; }
具體類中重寫鉤子方法
public class ConcreteBuilder extends Builder { ... @Override public boolean isCNeed() { return true; } }
控制器根據鉤子方法來判斷某一個buildX()是否執行
public class Director { private Builder builder; public Director(Builder builder) { this.builder = builder; } public Product construct() { builder.buildPartA(); builder.buildPartB(); if(builder.isCNeed()){ builder.buildPartC(); } builder.buildPartC(); return builder.createProduct(); } }
將複雜對象的建立過程給封裝了起來,同時將對象的建立過程與對象自己隔離開了,可以使用相同的建立過程來建立不一樣的產品對象(提供不一樣的Builder實現類便可)