当前位置: 首页 > news >正文

Design Pattern: Builder 模式

原文:http://www.riabook.cn/doc/designpattern/BuilderPattern.htm

您想要建立一个迷宫产生程式,迷宫使用二维阵列来定义,0表示道路,1表示墙,2表示宝物,根据所定义的二维迷宫阵列,您想要程式自动产生各种不同材质的迷宫,例如砖墙迷宫,钻石迷宫等等。 
您可以在程式中定义两个角色,一个是指导迷宫建立的Director角色,一个是按照指导者指示建立迷宫的Builder角色,Director根据定义的迷宫阵列来指导Builder,只要更换Builder,就可以完成不同材质的迷宫。 
可以使用下面的UML 类别图来表示上述的概念:

Builder

实际上的程式设计如下:

  • 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

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

Builder

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


==============================================================================
本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/04/23/2466966.html,如需转载请自行联系原作者

相关文章:

  • xml 相关操作
  • activity添加切换动画之后出现的黑色背景问题
  • GNU make manual 翻译( 一百五十八)
  • Linux自学笔记——nginx详解
  • POJ 1722 DP
  • centos搭建ssh
  • Direct2D入门
  • Mina2.0框架源码剖析(二)
  • 64位ubuntu下安装32位jdk
  • response.setHeader()的用法
  • PCIE BAR空间
  • HDU5115:Dire Wolf——题解+翻译
  • JS常用代码
  • [iOS]中字体样式设置 API
  • 20个Jquery表单插件
  • 【面试系列】之二:关于js原型
  • Bootstrap JS插件Alert源码分析
  • bootstrap创建登录注册页面
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • Python - 闭包Closure
  • Shadow DOM 内部构造及如何构建独立组件
  • Vue实战(四)登录/注册页的实现
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • 从零搭建Koa2 Server
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 前端学习笔记之观察者模式
  • 三分钟教你同步 Visual Studio Code 设置
  • 想写好前端,先练好内功
  • 学习ES6 变量的解构赋值
  • 数据可视化之下发图实践
  • # 达梦数据库知识点
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (三) diretfbrc详解
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (原創) 未来三学期想要修的课 (日記)
  • (转) RFS+AutoItLibrary测试web对话框
  • (转)母版页和相对路径
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .NET Core Web APi类库如何内嵌运行?
  • .Net IE10 _doPostBack 未定义
  • .Net(C#)常用转换byte转uint32、byte转float等
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .net中生成excel后调整宽度
  • @RequestBody的使用
  • @Transactional 竟也能解决分布式事务?
  • [<MySQL优化总结>]
  • [ANT] 项目中应用ANT
  • [AX]AX2012开发新特性-禁止表或者表字段
  • [bbk5179]第66集 第7章 - 数据库的维护 03
  • [C# WPF] 如何给控件添加边框(Border)?
  • [C#][opencvsharp]opencvsharp sift和surf特征点匹配
  • [CF494C]Helping People