读书人

Design Pattern: Builder 形式

发布时间: 2012-09-02 21:00:34 作者: rapoo

Design Pattern: Builder 模式
  您想要建立一个迷宫产生程式,迷宫使用二维阵列来定义,0表示道路,1表示墙,2表示宝物,根据所定义的二维迷宫阵列,您想要程式自动产生各种不同材质的迷宫,例如砖墙迷宫,钻石迷宫等等。

  您可以在程式中定义两个角色,一个是指导迷宫建立的Director角色,一个是按照指导者指示建立迷宫的Builder角色,Director根据定义的迷宫阵列来指导Builder,只要更换Builder,就可以完成不同材质的迷宫。

  可以使用下面的UML 类别图来表示上述的概念:
builder-1.jpg


  实际上的程式设计如下:

MazeDirector.java

    public class MazeDirector {        private int[][] maze;        private IMazeBuilder mazeBuilder;        public void setMaze(int[][] maze) {            this.maze = maze;        }        public void setMazeBuilder(IMazeBuilder mazeBuilder) {            this.mazeBuilder = mazeBuilder;        }        public void buildMaze() {            for(int i = 0; i < maze.length; i++) {                for(int j = 0; j < maze[i].length; j++) {                    // 由于mazeBuilder是IMazeBuilder型态               // 所以无论Builder实例为何,这边的程式都无需变动               switch (maze[i][j]) {                        case 0:                            mazeBuilder.createRoadBlock();                            break;                        case 1:                            mazeBuilder.createWallBlock();                            break;                        case 2:                            mazeBuilder.createTreasureBlock();                            break;                        default:                            System.out.println("undefined");                    }                }                mazeBuilder.nextRow();                }        }    } 

IMazeBuilder.java
public interface IMazeBuilder {    public void createRoadBlock();    public void createWallBlock();    public void createTreasureBlock();    public void nextRow();} 

SoliderMazeBuilder.java
    public class SolidMazeBuilder implements IMazeBuilder {        public void createWallBlock() {            System.out.print("-");        }        public void createRoadBlock() {            System.out.print(" ");        }        public void createTreasureBlock() {            System.out.print("$ ");        }        public void nextRow() {            System.out.println();        }    } 

DiamondMazeBuilder.java
    public class DiamondMazeBuilder implements IMazeBuilder {        public void createWallBlock() {            System.out.print("◇");        }        public void createRoadBlock() {            System.out.print(" ");        }        public void createTreasureBlock() {            System.out.print("* ");        }        public void nextRow() {            System.out.println();        }    }

使用下面的程式来测试一下,它将产生两个迷宫图形:
    public class Main {        public static void main(String[] args) {            int[][] maze = {{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 mazeDirector = new MazeDirector();            mazeDirector.setMaze(maze);            System.out.println("Build SolidMaze....");            mazeDirector.setMazeBuilder(new SolidMazeBuilder());            mazeDirector.buildMaze();            System.out.println("Build DiamondMaze....");            mazeDirector.setMazeBuilder( new DiamondMazeBuilder());            mazeDirector.buildMaze();        }    }

builder-2.jpg


  在迷宫例子中并没有产生或返回产品物件,这视您的需求而定,迷宫例子只是将结果输出至主控台,您也可以设计一个产品物件,或是将结果直接输出为文件。
  在 Gof 中有给出了一个不错的例子,以设计文件剖析器为例,该剖析器可以将文件转换为其它的格式,以DOC文件剖析器为例好了,假设希望析剖器可以将DOC文件转换为RTF或是PDF文件,可以如下设计结构:
builder-3.jpg


  简单来说,建筑者模式适用的场合,在于使得您可以依赖抽象的建筑蓝图,而实际建造时可以使用不同的实例,这是其之所以命为Builder的原因。


我的小结:Builder模式中,负责控制和组装的类的代码不变,只修改或增加负责构建具体细节的类。用一个地图做比喻的话,可理解成:地图里控制具体单元格的图片那部分类是变动的,而根据地图数据创建单元格的那部分代码或类是不变的。

读书人网 >编程

热点推荐