生成器模式(Builder)-- 对象创建型模式

1. 动机

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。一个RTF(Rich Text Format)文档交换格式的阅读器应能将RTF转换为多种正文格式。该阅读器可以将RTF文档转换成普通ASCII文本或转换成一个能以交互方式编辑的正文窗口组件。但问题在于可能转换的数目是无限的。因此要能够很容易实现新的转换的增加,同时却不改变RTF阅读器。其实也就是,前面的数据接卸(源头处理)归解析,后续的显示处理,由显示处理的部分来完成。在数据解析和显示处理之间架设一个标准的桥梁,供两方通知交互。

2. 描述

当RTF Reader对RTF文档进行语法分析时,它使用TextConverter去做转换。无论何时RTF Reader识别了一个RTF标记(或是普通正文或是一个RTF控制字),它都发送一个请求给TextConverter去转换这个标记。TextConverter对象负责进行数据转换以及用特定格式表示该标记。至于具体转换成什么样的显示,完全有实际TextConverter来处理。
    TextConvert的子类对不同转换和不同格式进行特殊处理。例如,一个ASCIIConverter只负责转换普通文本,而忽略其他转换请求。另一方面,一个TeXConverter将会为实现对所有请求的操作,以便生成一个获取正文中所有风格信息的TEX表示。一个TextWidgetConverter将生成一个复杂的用户界面对象以便用户浏览和编辑正文。
    这里有个关键,就是RTF Reader解析出来的Symbol是所有TextConvert都能看的懂的,也许某个TextConvert不一定会去处理这个symbol,他有可能忽略掉这个Symbol,但忽略,也是一种看懂的行为。

image

 

 

image

 

参与者:

  • Builder(TextConvert)

为创建一个Product对象的各个部件制定抽象接口

  • ConcreteBuilder (AsciiConverter、TeXConverter、TextWidgetConverter)

实现Builder的接口,以构造和装配该产品的各个部件

定义并明确它所创建的表示

提供一个检索产品的接口(例如, GetAsciiText和GetTextWidget)

  • Director (RTFReader)

构造一个使用Builder接口的对象

  • Product (AsciiText、TeXText、TextWidget)

表示被构造的复杂对象。ConcreteBuilder创建该铲平的内部表示并定义它的装配过程。

包含定义组成部件的类,包括将这些部件装配成最终产品的接口

image

 

从上图也可以看出, Builder模式除了“生成”的含义外,还强调了通过aDirector来组装所有aConcreteBuilder的过程。

class MazeBuilder {   //这个是Builder
public:
    virtual void BuildMaze() {}
    virtual void BuildRoom(int room) {}
    virtual void BuildDoor

    virtual Maze * GetMaze() {return 0;}

protected:
    MazeBuilder();
};

Maze * MazeGame::CreateMaze(MazeBuilder & builder) {   //这个就是Director
    builder.BuildMaze();

    builder.BuildRoom(1);
    builder.BuildRoom(2);
    builder.BuildRoom(1, 2);

    return builder.GetMaze;
}

class StanderdMazeBuilder : public MazeBuilder {    //这个是ConcreteBuilder
public:
    StandardMazeBuilder();

    virtual void BuildMaze();
    virtual void BuildRoom(int);
    virtual void BuildDoor(int, int);
    virtual Maze * GetMaze();

private:
    Direction CommonWall(Room *, Room*);
    Maze * _currentMaze;
};

void StandardMazeBuiler::StandardMazeBuilder() {
        _currentMaze = 0;
}


void StandardMazeBuiler::BuildMaze() {    //这是ConcreteBuilder的BuilPartA
        _currentMaze = new Maze;
};


Maze * StandardMazeBuiler::GetMaze() {    //这是ConcreteBuilder的GetResult
        Return _currentMaze;
}


void StandardMazeBuiler::BuildRoom(int n) {    //这是ConcreteBuilder的BuilPartB
    Room * room = new Room(n);
    room->SetSide(North, new Wall);
    room->SetSide(South, new Wall);
    room->SetSide(West, new Wall);
    room->SetSide(East, new Wall);

    _currentMaze->AddRoom(room)
}


//作为Client:
Maze *maze;
MazeGame game; //aDirector
StandardMazeBuilder builder; //aConcreteBuilder

Game.CreateMaze(builder); //Constructor
maze = builder.GetMaze();  //getResult

 

3. 适用性

 

  1. 他使得你可以该表一个产品的内部表示
  2. 它将构造代码和表示代码分开:Builder模式通过封装一个复杂对象的创建和表示方式提高了对象的模块性。客户不需要知道定义产品内部结构的类的所有信息;这些类是不出现在Builder接口中的。每个ConcreteBuilder包含了创建和装配一个特定产品的所有代码。这些代码只需要写一次;然后不同的Director可以复用它以在相同部件集合的基础上构作不同的Product。在前面的RTF例子中,我们可以为RTF格式以外的格式定义一个阅读器,比如一个SGMLReader,并使用相同的TextConverter生成SGML文档的ASCIIText、TeXText和TextWidget译本。
  3. 它使你可对构造过程进行更精细的控制:Builder模式与一下子就生成产品的创建型模式不同,它是在导向者的控制下一步一步构造产品的。仅当该产品完成时导向者才从生成器中取回它。因此Builder接口相比其他创建型模式能更好的反映产品的构造过程。这使你可以更精细的控制构建过程,从而能更精细的控制所得产品的内部结构。

转载于:https://www.cnblogs.com/lday/p/3793432.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值