定義:將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
類型:創建類模式
類圖:
四個要素
- 產品類:一般是一個較為復雜的對象,也就是說創建對象的過程比較復雜,一般會有比較多的代碼量。在本類圖中,產品類是一個具體的類,而非抽象類。實際編程中,產品類可以是由一個抽象類與它的不同實現組成,也可以是由多個抽象類與他們的實現組成。
- 抽象建造者:引入抽象建造者的目的,是為了將建造的具體過程交與它的子類來實現。這樣更容易擴展。一般至少會有兩個抽象方法,一個用來建造產品,一個是用來返回產品。
- 建造者:實現抽象類的所有未實現的方法,具體來說一般是兩項任務:組建產品;返回組建好的產品。
- 導演類:負責調用適當的建造者來組建產品,導演類一般不與產品類發生依賴關系,與導演類直接交互的是建造者類。一般來說,導演類被用來封裝程序中易變的部分。
代碼實現
產品的抽象類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package Builder; import java.util.ArrayList; public abstract class AbstractProduct { //記錄執行順序 private ArrayList<String> part = new ArrayList<String>(); public abstract void doSomething(); public abstract void doOtherthing(); //final,子類不可重寫 final public void executive(){ for ( int i= 0 ;i< this .part.size();i++){ String actionName = this .part.get(i); if (actionName.equals( "doSomething" )){ this .doSomething(); } else if (actionName.equals( "doOtherthing" )){ this .doOtherthing(); } } } //final,子類不可重寫 final public void setPart(ArrayList<String> part){ this .part = part; } } |
產品的實現類:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package Builder; public class Product extends AbstractProduct{ //子類具體描述步驟 public void doSomething(){ System.out.println( "will do something..." ); } public void doOtherthing() { System.out.println( "Something has done.Otherthing will be done..." ); } } |
建造者抽象類:
1
2
3
4
5
6
7
8
9
10
11
12
|
package Builder; import java.util.ArrayList; public abstract class Builder { //設置產品的不同部分,以獲得不同的產品 public abstract void setPart(ArrayList<String> part); //建造產品 public abstract Product buildProduct(); } |
建造者實現類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package Builder; import java.util.ArrayList; public class ConcreteProduct extends Builder{ private Product product = new Product(); public void setPart(ArrayList<String> part) { this .product.setPart(part); } public Product buildProduct() { return this .product; } } |
導演類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package Builder; import java.util.ArrayList; //對不同產品的生產順序再封裝,對高層屏蔽細節 public class Director { private ArrayList<String> part = new ArrayList<String>(); private Builder builder = new ConcreteProduct(); public Product getAProduct() { this .part.clear(); this .part.add( "doSomething" ); this .part.add( "doOtherthing" ); builder.setPart(part); return builder.buildProduct(); } } |
客戶端:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package Builder; public class Client { public static void main(String[] args) { Director director = new Director(); System.out.println( "將產生10個產品" ); for ( int i= 1 ;i< 11 ;i++){ System.out.println( "第" + i + "個產品" ); director.getAProduct().executive(); System.out.println(); } } } |
建造者模式的優點
首先,建造者模式的封裝性很好。使用建造者模式可以有效的封裝變化,在使用建造者模式的場景中,一般產品類和建造者類是比較穩定的,因此,將主要的業務邏輯封裝在導演類中對整體而言可以取得比較好的穩定性。
其次,建造者模式很容易進行擴展。如果有新的需求,通過實現一個新的建造者類就可以完成,基本上不用修改之前已經測試通過的代碼,因此也就不會對原有功能引入風險。
建造者模式與工廠模式的區別
我們可以看到,建造者模式與工廠模式是極為相似的,總體上,建造者模式僅僅只比工廠模式多了一個“導演類”的角色。在建造者模式的類圖中,假如把這個導演類看做是最終調用的客戶端,那么圖中剩余的部分就可以看作是一個簡單的工廠模式了。
與工廠模式相比,建造者模式一般用來創建更為復雜的對象,因為對象的創建過程更為復雜,因此將對象的創建過程獨立出來組成一個新的類——導演類。也就是說,工廠模式是將對象的全部創建過程封裝在工廠類中,由工廠類向客戶端提供最終的產品;而建造者模式中,建造者類一般只提供產品類中各個組件的建造,而將具體建造過程交付給導演類。由導演類負責將各個組件按照特定的規則組建為產品,然后將組建好的產品交付給客戶端。
總結
建造者模式與工廠模式類似,他們都是建造者模式,適用的場景也很相似。一般來說,如果產品的建造很復雜,那么請用工廠模式;如果產品的建造更復雜,那么請用建造者模式。