//---------------------------15/04/08----------------------------

//builder 生成器(建造者)模式---对象创建型模式

/*

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

2:动机

3:适用性:

1>当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时。

2>当构造过程必须允许被构造的对象有不同的表示时。

4:结构:

Director:

builder----------------------------->Builder:

Construct()                         BuildPart()

{ for all objects in structure          |

{  builder->BuildPart()}  }         |

ConcreteBuilder: - - - ->Product

BuildPart()

GetResult()

5:参与者:

1>Builder:为创建一个Product对象的各个部件指定抽象接口。

2>ConcreteBuilder:

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

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

3)提供一个检索产品的接口.

3>Director:构造一个使用Builder接口的对象。

4>Product:

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

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

6:协作:

1>客户创建Director对象,并用它所想要的Builder对象进行配置。

2>一旦产品部件被生成,导向器就会通知生成器。

3>生成器处理导向器的请求,并将部件添加到该产品中。

4>客户从生成器中检索产品。(得到产品)

下面的图说明了Builder和Director和客户的协作:

aClient                 aDirector           aConcreteBuilder

|                       |                       |

new ConcreteBuilder---------------------------->|

new Director(aCon..)--->|                       |

|                       |                       |

Construct()------------>|BuildPartA()---------->|

|                       BuildPartB()----------->|

|                       BuildPartC()----------->|

|                       |                       |

GetResult()------------------------------------>|

|                       |                       |

7:效果:

1>它使你可以改变一个产品的内部表示。

Builder给Director只提供了抽象接口,隐藏了内部装配过程,所以想要改变

内部表示的时候,只需要定义一个新的Builder就行了。

2>它将构造代码和表示代码分开。

ConcreteBuilder已经提供了创建一个产品的所有代码,不同的Director可以复用它

以在相同部件集合的基础上构造不同的Product。

3>它使你可以对构造过程进行更精密的控制。

与一下子就生产产品的创建型模式不同,Builder模式是在导向者的控制下一步一步构造产品的。

所以可以更精细地控制构造过程。

8:实现:

1>要有一个抽象的Builder类为Director提供产品每一个部分创建的接口。ConcreteBuilder

只用对感兴趣的部分实现操作就行。

2>装配和构造接口:Builder类的接口必须足够普遍。

有一个需要考虑的点是,Builder创建PartB时可能需要用到PartA的对象,

所以,可以从PartA那里返回一个PartA对象,再由Director传入PartB。

3>为什么产品没有抽象类:一般生存器生成的产品的表示相差十分之大,以至于难以提供公共父类。

9:代码示例:                                                                     */

//定义一个抽象类,接口都是空操作,不声明成纯虚函数是因为ConcreteBuilder只需要实现自己感兴趣的接口

class MazeBuilder

{

public:

virtual void BuildMaze(){}

virtual void BuildRoom(int room) {}

virtual void BuildDoor(int roomFrom,
int roomTo){}

virtual Maze* GetMaze(){return
;}

protected:

MazeBuilder();

};

//Director,根据传入的Builder创建迷宫

Maze* MazeGame::CreateMaze(MazeBuilder& builder)

{

//这里想怎么创建就怎么创建,无需关注底部实现细节

builder.BuildMaze();

builder.BuildRoom();

builder.BuildRoom();

builder.BuildDoor(,
);

return builder.GetMaze();

}

class StandardMazeBuilder :
public MazeBuilder

{

public:

StandardMazeBuilder();

virtual void BuildMaze();

virtual void BuildRoom(int);

virtual void BuildDoor(int,
int);

virtual Maze* GetMaze();

private:

Direction CommonWall(Room*, Room*);

Maze* _currentMaze;

};

//具体的builder

StandardMazeBuilder::StandardMazeBuilder()

{

_currentMaze =
;

}

void StandardMazeBuilder::BuildMaze()

{

_currentMaze =
new Maze;

}

Maze* StandardMazeBuilder::GetMaze()

{

return _currentMaze;

}

void StandardMazeBuilder::BuildRoom(int n)

{

if(!_currentMaze->RoomNo(n))

{

Room* room =
new Room(n);

_currentMaze->AddRoom(room);

room->SetSide(North,
new Wall);

room->SetSide(South,
new Wall);

room->SetSide(East,
new Wall);

room->SetSide(West,
new Wall);

}

}

void StandardMazeBuilder::BuildDoor(int n1,
int n2)

{

Room* r1 = _currentMaze->RoomNo(n1);

Room* r2 = _currentMaze->roomNo(n2);

Door* d =
new Door(r1, r2);

r1->SetSide(CommonWall(r1,r2), d);

r2->SetSide(CommonWall(r2,r1), d);

}

//如果我们需要有个个会爆炸的门可以如下实现。

void StandardMazeBuilder::BuildBoomedDoor(int n1,
int n2)

{

Room* r1 = _currentMaze->RoomNo(n1);

Room* r2 = _currentMaze->roomNo(n2);

Door* d =
new BoomedDoor(r1, r2);

r1->SetSide(CommonWall(r1,r2), d);

//  感觉CommonWall实现为room的成员函数更好,r1.CommonWall(r2)这样更好理解

r2->SetSide(CommonWall(r2,r1), d);

}

//十分简单

Maze* maze;//Product

MazeGame game;//Director

StandardMazeBuilder builder;//Builder

game.CreateMaze(builder);

maze = builder.GetMaze();

//上面的两句可以合并成:

maze = game.CreateMaze(builder);
//因为create的实现里已经调用GetMaze了

class CountingMazeBuilder :
public MazeBuilder

{

public:

CountingMazeBuilder();

virtual void BuildMaze();

virtual void BuildRoom(int);

virtual void BuildDoor(int,
int);

virtual void AddWall(int, Director);

void GetCounts(int&,
int&) const;

private:

int _doors;

int _rooms;

};

CountingMazeBuilder::CountingMazeBuilder():_rooms(), _doors()

{

//_rooms = _doors = 0;
应该使用初始化列表初始化

}

inline
void CountingMazeBuilder::BuildRoom(int)

{

++_rooms;

}

inline
void CountingMazeBuilder::BuildDoor(int)

{

++_doors;

}

inline CountingMazeBuilder::GetCounts(int& rooms,
int& doors) const

{

rooms = _rooms;

doors = _doors;

}

//这就是一个计数的builder,感觉如果需要计数,直接放在基类里就行了,
想用的时候调用基类的方法一次就好。

设计模式 笔记 生成器(建造者)模式 Builder的更多相关文章

  1. 设计模式系列之建造者模式(Builder Pattern)——复杂对象的组装与创建

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  2. 【原】iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数

    本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解释建造者模式的概念,那些东西太虚了.设计模式这种东西是为了解决实际问题的,不能为了设计模式而设计模式, ...

  3. iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数

    转自:http://www.cnblogs.com/wengzilin/p/4365855.html 本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解 ...

  4. IOS设计模式浅析之建造者模式(Builder)

    定义 "将一个复杂对象的构建与它的表现分离,使得同样的构建过程可以创建不同的表现". 最初的定义出现于<设计模式>(Addison-Wesley,1994). 看这个概 ...

  5. Net设计模式实例之建造者模式(Builder Pattern)

    一.建造者模式简介(Brief Introduction) 建造者模式(Builder Pattern),将一个复杂对象的构建与它的表示分离,使的同样的构建过程可以创建不同的表示. 建造者模式的优点是 ...

  6. 设计模式学习之建造者模式(Builder,创建型模式)(6)

    假如我们需要建造一个房子,并且我们也不知道如何去建造房子,所以就去找别人帮我们造房子 第一步: 新建一个房子类House,里面有房子该有的属性,我们去找房子建造者接口HouseBuilder,我们要建 ...

  7. 设计模式—建造者模式(Builder)

    title: 设计模式-建造者模式 建造者模式(Builder)是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节.建造者模式属于对 ...

  8. 乐在其中设计模式(C#) - 建造者模式(Builder Pattern)

    原文:乐在其中设计模式(C#) - 建造者模式(Builder Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 建造者模式(Builder Pattern) 作者:webabc ...

  9. 【设计模式】建造者模式 Builder Pattern

    前面学习了简单工厂模式,工厂方法模式以及抽象工厂模式,这些都是创建类的对象所使用的一些常用的方法和套路, 那么如果我们创建一个很复杂的对象可上面的三种方法都不太适合,那么“专业的事交给专业人去做”,2 ...

随机推荐

  1. poj_3253 Fence Repair

    Fence Repair Description Farmer John wants to repair a small length of the fence around the pasture. ...

  2. java8时间操作

    import java.time.*; import java.util.Date; /** * @Auther kejiefu * @Date 2018/5/17 0017 */ public cl ...

  3. Coursera-AndrewNg(吴恩达)机器学习笔记——第四周编程作业(多分类与神经网络)

    多分类问题——识别手写体数字0-9 一.逻辑回归解决多分类问题 1.图片像素为20*20,X的属性数目为400,输出层神经元个数为10,分别代表1-10(把0映射为10). 通过以下代码先形式化展示数 ...

  4. 系统升级win7 sp1后,ado,MSJRO.tlh error 问题

    MSJRO.tlh() : error C2501: '_RecordsetPtr' : missing storage-class or type specifiers MSJRO.tlh() : ...

  5. 团队作业6--展示博客(Alpha版本)

    一.团队展示: 1.队名:软件1412--博客管理系统 2.队员学号(标记组长) 曾海明(组长):201421122036   周雅静(组员):201421122003  王珏(组员):2014211 ...

  6. Lombok快速上手(安装、使用与注解参数)

    目录 Lombok插件安装与使用说明 常见参数 lombok的依赖于安装 依赖管理 IDEA插件的安装 @Data小例子 扩展@ToString 构造器注解扩展 @Log及其他日志注解 资料链接 Lo ...

  7. facebook api & oauth protocal

    http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-10.5 http://stackoverflow.com/questions/14 ...

  8. Nginx反向代理及简单负载均衡配置

    nginx配置文件主要分为六个区域:main section.events section.http section.sever section.location section.upstream s ...

  9. 浅析Java虚拟机结构与机制[转]

    本文旨在给所有希望了解JVM(Java Virtual Machine)的同学一个概念性的入门,主要介绍了JVM的组成部分以及它们内部工作的机制和原理.当然本文只是一个简单的入门,不会涉及过多繁杂的参 ...

  10. 常用npm 命令

    npm 官方网站:npm的使用说明   安装模块 npm install 安装当前目录package.json文件中配置的dependencies模块   安装本地的模块文件 npm install ...