程式扎記: [OO 設計模式] Gossip@DesignPattern : Creational - Builder 模式

標籤

2014年5月13日 星期二

[OO 設計模式] Gossip@DesignPattern : Creational - Builder 模式

轉載自 這裡
前言 :
如果您有個物件必須建立,物件是由個別組件(Component)組合而成,個別組件建立非常複雜,但說明如何運用組件建立非常簡單,您希望將建立複雜組件與運用組件方式分離,則可以使用 Builder 模式. 舉例來說,您想要建立一個迷宮產生程式,迷宮使用二維陣列來定義,0表示道路,1表示牆,2表示寶物,根據所定義的二維迷宮陣列,您想要程式自動產生各種不 同材質的迷宮,例如磚牆迷宮,鑽石迷宮等。在不同的繪圖引擎下,建立各種材質非常複雜,但建立迷宮的表達方式很簡單,像是這邊要道牆,那邊要條路,旁邊要 放個寶藏之類的。
您可以在程式中定義兩個角色,一個是指導迷宮建立流程的 MazeDirector 角色,一個是建立迷宮中每個區塊的 MazeBuilder 角色 :
- Maze interface :
  1. package dp.builder;  
  2.   
  3. public interface Maze {public void paint();}  
- MazeBuilder :
  1. package dp.builder;  
  2.   
  3. public interface MazeBuilder {  
  4.     void buildRoad(int i, int j);  
  5.     void buildWall(int i, int j);  
  6.     void buildTreasure(int i, int j);  
  7.     Maze getMaze();  
  8. }  
- MazeDirector.java :
  1. package dp.builder;  
  2.   
  3. public class MazeDirector {  
  4.     private int[][] maze;  
  5.     private MazeBuilder builder;  
  6.       
  7.     MazeDirector(int[][] maze, MazeBuilder builder) {  
  8.         this.maze = maze;  
  9.         this.builder = builder;  
  10.     }  
  11.       
  12.     Maze build() {  
  13.         for(int i = 0; i < maze.length; i++) {  
  14.             for(int j = 0; j < maze[i].length; j++) {  
  15.                 switch (maze[i][j]) {  
  16.                     case 0:  
  17.                         builder.buildRoad(i, j);  
  18.                         break;  
  19.                     case 1:  
  20.                         builder.buildWall(i, j);  
  21.                         break;  
  22.                     case 2:  
  23.                         builder.buildTreasure(i, j);  
  24.                         break;  
  25.                 }  
  26.             }  
  27.         }  
  28.         return builder.getMaze();  
  29.     }  
  30. }  

您可以實作不同的 MazeBuilder,使用不同的材質來建立迷宮中每個區塊,例如 :
- PlainBuilder.java :
  1. package dp.builder;  
  2.   
  3. public class PlainBuilder implements MazeBuilder {  
  4.     private char[][] maze;  
  5.   
  6.     PlainBuilder(int i, int j) {  
  7.         this.maze = new char[i][j];  
  8.     }  
  9.   
  10.     public void buildRoad(int i, int j) {  
  11.         maze[i][j] = ' ';  
  12.     }  
  13.   
  14.     public void buildWall(int i, int j) {  
  15.         maze[i][j] = '□';  
  16.     }  
  17.   
  18.     public void buildTreasure(int i, int j) {  
  19.         maze[i][j] = '*';  
  20.     }  
  21.   
  22.     @Override  
  23.     public Maze getMaze() {  
  24.         return new Maze() {  
  25.             @Override  
  26.             public void paint() {  
  27.                 for (char[] row : maze) {  
  28.                     for (char ele : row) {  
  29.                         System.out.print(ele);  
  30.                     }  
  31.                     System.out.println();  
  32.                 }  
  33.             }  
  34.         };  
  35.     }  
  36.   
  37.     public static void main(String[] args) {  
  38.         final int[][] material = { { 1111111 },  
  39.                 { 1000021 }, { 1010101 },  
  40.                 { 1021011 }, { 1101011 },  
  41.                 { 1002001 }, { 1111111 } };  
  42.   
  43.         MazeDirector director = new MazeDirector(material, new PlainBuilder(  
  44.                 material.length, material[0].length));  
  45.         director.build().paint();  
  46.     }  
  47. }  
乍看之下,Builder 模式與 Abstract Factory 模式 很類似,其中最主要的差別在於,Abstract Factory 模式 著重在不同的工廠實作提供不同的一組產品給組件使用,產品之間並不見得有「部份」(Part of的概念。Builder 模式 則強調 Builder 中所建立的組件,彼此之間有著「部份」Part of的概念,並依 Director 的流程來建立組件與組件之間的關係,也就是說,Builder組件建立與Director流程指導之間為彼此合作關係為強調出兩者關係,或許取名叫Director-Builder模式會更適合). 可以使用下面的UML 類別圖來表示 Builder 模式 :

圖中 Builder 介面指的是,物件必須具有 Builder 所定義之公開協定,而非專指 Java 中的interface定義。對於靜態語言來說,例如 Java,必須使用型態來宣告變數,因此根據需求,可以使用 interfact 或 abstract class 來定義 Builder 所定義之公開協定。對於動態語言來說,例如 Python,真正的型態資訊是在物件之上(而非變數),因此要求的是物件必須具有 Buildert 之公開方法(無論是「哪一種」物件).

補充說明 :
Wiki : Builder Pattern
The builder pattern is a software design pattern. The intention is to abstract steps of construction of objects so that different implementations of these steps can construct different representations of objects. Often, the builder pattern is used to build products in accordance to the composite pattern, a structural pattern.
- Builder
Abstract interface for creating objects (product).
- Concrete Builder
Provides implementation for Builder. It is an object able to construct other objects. Constructs and assembles parts to build the objects.
- Director
The Director class is responsible for managing the correct sequence of object creation. It receives a Concrete Builder as a parameter and executes the necessary operations on it.
- Product
The final object that will be created by the Director using Builder.

This message was edited 16 times. Last update was at 25/02/2014 14:36:21

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!