轉載自 這裡
前言 :
如果您有個物件必須建立,物件是由個別組件(Component)組合而成,個別組件建立非常複雜,但說明如何運用組件建立非常簡單,您希望將建立複雜組件與運用組件方式分離,則可以使用 Builder 模式. 舉例來說,您想要建立一個迷宮產生程式,迷宮使用二維陣列來定義,0表示道路,1表示牆,2表示寶物,根據所定義的二維迷宮陣列,您想要程式自動產生各種不 同材質的迷宮,例如磚牆迷宮,鑽石迷宮等。在不同的繪圖引擎下,建立各種材質非常複雜,但建立迷宮的表達方式很簡單,像是這邊要道牆,那邊要條路,旁邊要 放個寶藏之類的。
您可以在程式中定義兩個角色,一個是指導迷宮建立流程的 MazeDirector 角色,一個是建立迷宮中每個區塊的 MazeBuilder 角色 :
- Maze interface :
- MazeBuilder :
- MazeDirector.java :
您可以實作不同的 MazeBuilder,使用不同的材質來建立迷宮中每個區塊,例如 :
- PlainBuilder.java :
乍看之下,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
前言 :
如果您有個物件必須建立,物件是由個別組件(Component)組合而成,個別組件建立非常複雜,但說明如何運用組件建立非常簡單,您希望將建立複雜組件與運用組件方式分離,則可以使用 Builder 模式. 舉例來說,您想要建立一個迷宮產生程式,迷宮使用二維陣列來定義,0表示道路,1表示牆,2表示寶物,根據所定義的二維迷宮陣列,您想要程式自動產生各種不 同材質的迷宮,例如磚牆迷宮,鑽石迷宮等。在不同的繪圖引擎下,建立各種材質非常複雜,但建立迷宮的表達方式很簡單,像是這邊要道牆,那邊要條路,旁邊要 放個寶藏之類的。
您可以在程式中定義兩個角色,一個是指導迷宮建立流程的 MazeDirector 角色,一個是建立迷宮中每個區塊的 MazeBuilder 角色 :
- Maze interface :
- package dp.builder;
- public interface Maze {public void paint();}
- package dp.builder;
- public interface MazeBuilder {
- void buildRoad(int i, int j);
- void buildWall(int i, int j);
- void buildTreasure(int i, int j);
- Maze getMaze();
- }
- package dp.builder;
- public class MazeDirector {
- private int[][] maze;
- private MazeBuilder builder;
- MazeDirector(int[][] maze, MazeBuilder builder) {
- this.maze = maze;
- this.builder = builder;
- }
- Maze build() {
- for(int i = 0; i < maze.length; i++) {
- for(int j = 0; j < maze[i].length; j++) {
- switch (maze[i][j]) {
- case 0:
- builder.buildRoad(i, j);
- break;
- case 1:
- builder.buildWall(i, j);
- break;
- case 2:
- builder.buildTreasure(i, j);
- break;
- }
- }
- }
- return builder.getMaze();
- }
- }
您可以實作不同的 MazeBuilder,使用不同的材質來建立迷宮中每個區塊,例如 :
- PlainBuilder.java :
- package dp.builder;
- public class PlainBuilder implements MazeBuilder {
- private char[][] maze;
- PlainBuilder(int i, int j) {
- this.maze = new char[i][j];
- }
- public void buildRoad(int i, int j) {
- maze[i][j] = ' ';
- }
- public void buildWall(int i, int j) {
- maze[i][j] = '□';
- }
- public void buildTreasure(int i, int j) {
- maze[i][j] = '*';
- }
- @Override
- public Maze getMaze() {
- return new Maze() {
- @Override
- public void paint() {
- for (char[] row : maze) {
- for (char ele : row) {
- System.out.print(ele);
- }
- System.out.println();
- }
- }
- };
- }
- public static void main(String[] args) {
- final int[][] material = { { 1, 1, 1, 1, 1, 1, 1 },
- { 1, 0, 0, 0, 0, 2, 1 }, { 1, 0, 1, 0, 1, 0, 1 },
- { 1, 0, 2, 1, 0, 1, 1 }, { 1, 1, 0, 1, 0, 1, 1 },
- { 1, 0, 0, 2, 0, 0, 1 }, { 1, 1, 1, 1, 1, 1, 1 } };
- MazeDirector director = new MazeDirector(material, new PlainBuilder(
- material.length, material[0].length));
- director.build().paint();
- }
- }
圖中 Builder 介面指的是,物件必須具有 Builder 所定義之公開協定,而非專指 Java 中的interface定義。對於靜態語言來說,例如 Java,必須使用型態來宣告變數,因此根據需求,可以使用 interfact 或 abstract class 來定義 Builder 所定義之公開協定。對於動態語言來說,例如 Python,真正的型態資訊是在物件之上(而非變數),因此要求的是物件必須具有 Buildert 之公開方法(無論是「哪一種」物件).
補充說明 :
* Wiki : Builder Pattern
This message was edited 16 times. Last update was at 25/02/2014 14:36:21
沒有留言:
張貼留言