《设计模式》学习笔记(5)——创建者模式(Builder)

1、意图
    将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

2、别名
    无

3、为什么会使用Builder模式
    在使用Word的时候,我们可以将文档存为多种格式,如RTF、txt、doc等等。假设我们在转换过程中是根据不同的元素来进行转化的,比如可以将转换分为字母转换、字体转换和段落标记的转换,且每次转换都会有这三个步骤。而且,未来可能还需要加入我们目前仍然未知的格式。则这里很显然我们可以抽象出这三个步骤的接口,并在其子类中实现;然后将这三个部分组合起来,就成为了我们所需要的东西。这样的一种方法便被称为了Builder模式。

4、适用性
    以下情况下可以使用此模式:

    • 需要生成的产品对象有复杂的内部结构。
    • 需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。
    • 在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到。
 
5、实例
    我们仍然沿用前面的迷宫例子:我们现在需要一个这样的标准迷宫:它只有两个相邻的房间,编号为1的房间东面是一扇门,这扇门是与编号为2的房间共用的,其他的面都为墙壁。  

6、结构图示     
    我们现在使用Builder模式来创建它,首先看结构图示:
 

    在这里,抽象类MazeBuilder称为builder,它创建了一套公共的接口,指出了构建一个迷宫所需要的操作并提供了一个检索产品的方法;但真正的实现部分是在下面继承自它的StandardMazeBuilder子类中。里面的MazeGame又称为director,因为它负责构造一个使用builder的对象。这里的Product显然就是Maze了,它由StandardMazeBuilder装配而成。

7、协作关系
    • 首先是客户创建director,并配置所需要的builder的部件。
    • 一旦需要产品部件,director会给builder一个通知。
    • builder会检索如何去实现director的需求,生成部件并添加到产品。
    • 最终客户从builder中去检索所需要的产品。

如下图

8、代码实现
    这里仅仅作些示例代码,希望需要全部代码的可在文章最后的链接处下载。

首先看builder的定义,上面的结构图已经清晰的指出它是一个抽象类。

    public abstract class MazeBuilder
    
{
        
protected MazeBuilder()
        
{

        }


        
public abstract void BuildMaze();

        
public abstract void BuildRoom(int roomNo);

        
public abstract void BuildDoor(int roomFrom, int roomTo);

        
public abstract Maze GetMaze();
    }


再来看看director,它定义了需要什么样的产品并返回所生成的产品。

    public class MazeGame
    
{
        
public MazeGame()
        
{

        }


        
public Maze CreateMaze(MazeBuilder builder)
        
{
            builder.BuildMaze();

            builder.BuildRoom(
1);
            builder.BuildRoom(
2);
            builder.BuildDoor(
12);

            
return builder.GetMaze();
        }

    }

客户只需简单创建director就可以得到所构建的产品
            MazeGame game = new MazeGame();
            StandardMazeBuilder builder 
= new StandardMazeBuilder();

            game.CreateMaze(builder);
            Maze maze 
= builder.GetMaze();


9、使用builder模式的效果
    1)它让你可以改变一个产品的内部表示。因为你总是需要通过director来调用抽象出来的builder接口。
    2)构造代码与表示代码分开了。举个例子:如果你有个产品是由A、B、C三部分生成,但B有两种不同的实现而造成有两种产品。那么对于A和C你仍然只需要写一次代码,然后通过配置director而得到不同的产品。
    3)你可以更精确的控制如何构造产品。由于产品是一部一部构建起来的,因此你可以决定构建的顺序并控制其内部结构。

10、相关模式
    Abstract Factory与Builder相似,他们都可以创建复杂对象。主要区别就是builder着重一步步构造复杂的产品对象,而Abstract Factory着重生成一个系列的产品对象。另外一个就是builder是最后才返回产品,而Abstract Factory则立即返回。
    Composite通常由Builder生成。

posted @ 2005-05-10 22:04    阅读(532)  评论(0编辑  收藏  举报