建造者模式利用一個導演者對象和一個建造者對象一個一個的創造出所有的零件,從而建造出完整的產品對象。建造者模式將產品的結構和產品的零件建造過程對客戶端隱藏起來,把對建造過程進行指揮的責任和具體的建造者零件的責任分割開來,達到責任劃分和封裝的作用。
類圖:
產品類
1 class Product { 2 private String name; 3 private String type; 4 public void showProduct(){ 5 System.out.println("名稱:"+name); 6 System.out.println("型號:"+type); 7 } 8 public void setName(String name) { 9 this.name = name; 10 } 11 public void setType(String type) { 12 this.type = type; 13 } 14 }
抽象建造者
1 abstract class Builder { 2 public abstract void createPart(String arg1, String arg2); 3 public abstract Product getProduct(); 4 }
具體建造者
1 class ConcreteBuilder extends Builder { 2 private Product product = new Product(); 3 4 public Product getProduct() { 5 return product; 6 } 7 8 public void createPart(String arg1, String arg2) { 9 product.setName(arg1); 10 product.setType(arg2); 11 } 12 }
導演者
1 public class Director { 2 private Builder builder = new ConcreteBuilder(); 3 public Product getAProduct(){ 4 builder.createPart("寶馬汽車","X7"); 5 return builder.getProduct(); 6 } 7 public Product getBProduct(){ 8 builder.createPart("奧迪汽車","Q5"); 9 return builder.getProduct(); 10 } 11 }
上面的只是建造者模式最基本的用法,現實生活中有很多建造者模式的變形,如產品有多個零件組成,所以要先創建產品零件,在利用具體的產品零件創造出產品,這樣就需要在建造者中先一步一步創建零件,再組裝產品;每個產品的零件不一定樣,為每一個產品創建具體的建造者。等等還有很多的變形。那麼在什麼時候使用建造者模式呢:
1、需要生成的對象有復雜的內部結構,每個內部成分本身可以是對象,也可以僅僅是一個對象的一個組成部分。
2、需要生成的對象的屬性相互依賴。建造者模式可以強制實行一種分步驟進行的建造過程。因此,如果產品對象的一個屬性必須在另一個屬性被賦值之後才可以被賦值。
3、對象的創建過程中會使用到系統中其他一些對象,這些對象在產品的創建過程中不易得到。
首先,建造者模式的封裝性很好。使用建造者模式可以有效的封裝變化,在使用建造者模式的場景中,一般產品類和建造者類是比較穩定的,因此,將主要的業務邏輯封裝在導演類中對整體而言可以取得比較好的穩定性。
其次,建造者模式很容易進行擴展。如果有新的需求,通過實現一個新的建造者類就可以完成,基本上不用修改之前已經測試通過的代碼,因此也就不會對原有功能引入風險。
前面剛剛介紹了工廠模式,它們都是創建模式。 我們可以看到,建造者模式與工廠模式是極為相似的,總體上,建造者模式僅僅只比工廠模式多了一個“導演類”的角色。在建造者模式的類圖中,假如把這個導演類看做是最終調用的客戶端,那麼圖中剩余的部分就可以看作是一個簡單的工廠模式了。
與工廠模式相比,建造者模式一般用來創建更為復雜的對象,因為對象的創建過程更為復雜,因此將對象的創建過程獨立出來組成一個新的類——導演類。也就是說,工廠模式是將對象的全部創建過程封裝在工廠類中,由工廠類向客戶端提供最終的產品;而建造者模式中,建造者類一般只提供產品類中各個組件的建造,而將具體建造過程交付給導演類。由導演類負責將各個組件按照特定的規則組建為產品,然後將組建好的產品交付給客戶端。
因此,在復雜對象的創建過程中一般既有建造者模式也有工廠模式,利用工廠模式返回不同的零件,在利用建造者模式將不同的零件組裝成更為復雜的產品。工廠模式處於更加具體的尺度上,而建造者模式處於更加宏觀的尺度上。