设计模式 笔记 生成器(建造者)模式 Builder

//---------------------------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
0;}

protected:

MazeBuilder();

};

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

Maze* MazeGame::CreateMaze(MazeBuilder& builder)

{

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

builder.BuildMaze();

builder.BuildRoom(1);

builder.BuildRoom(2);

builder.BuildDoor(1,
2);

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 =
0;

}

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(0), _doors(0)

{

//_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,感觉如果需要计数,直接放在基类里就行了,
想用的时候调用基类的方法一次就好。

时间: 2024-10-04 08:30:13

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

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

title: 设计模式-建造者模式 建造者模式(Builder)是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节.建造者模式属于对象创建型模式.我们获得一个对象的时候不是直接new这个对象出来,而是对其建造者进行属性设置,然后建造者在根据设置建造出各个对象出来.建造者模式又可以称为生成器模式. 模式结构 一个标准的建造者模式包含如下角色: Builder:抽象建造者 ConcreteBuilder:具体建造者 Director

说说设计模式~建造者模式(Builder)

返回目录 建造者模式是我的"设计模式"里创建型模式里的最后一篇,这种模式在实现中,很多架构都用到了,如MVC,MVP,MVVM,它们都是有建造者模式的精髓的,即,创建与表现分享,我们的MVC何尝不是,我们的MVVM又何尝不是呢,我们做软件的,换肤是常有的事,其实换肤的实现不就是建造者模式最好的体现吗,呵呵. 定义 将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式. 何时能用到它? 1 当创建复杂对象的算法应该独立于该对象的组成部分以

建造者模式<Builder>

概述 将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式 角色 建造者(Builder):为创建一个产品对象的各个部件指定抽象接口. 具体建造者(ConcreteBuilder):实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并 提供一个检索产品的接口 产品(Product):表示被构造的复杂对象.ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最

设计模式五:建造者模式

建造者模式又称为生成器模式,它是一种较为复杂.使用频率也相对较低的创建型模式.建造者模式为客户端返回的不是一个简单的产品,而是一个由多个部件组成的复杂产品. 建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.建造者模式是一种对象创建型模式. //Actor角色类:复杂产品,考虑到代码的可读性,只列出部分成员属性,且成员属性的类型均为String,真实情况下,有些成员属性的类型需自定义 class Actor { private

设计模式学习04—建造者模式

一.动机与定义 创建对象时,我们知道可以使用工厂方式来创建,使调用者和具体实现解耦,但是有一种情况,当要创建的多个对象之间重复性较大,只有创建步骤.组装顺序或者内部构件不同时,工厂模式就需要进一步的演化了,如我们去KFC,有很多种套餐,比如套餐1(薯条+可乐+汉堡),套餐2(鸡肉卷+薯条+可乐),这个套餐就是我们要获取的复杂对象,那么程序如何创建出这种对象呢. 我们看到套餐的内容很多是一样的,那么我们是不是可以考虑将创建单个食品(如鸡肉卷.可乐等)方法提取出来,使用单独一个类协调这些食品的组合比

我的设计模式:从模版设计模式谈到建造者模式

1.模版设计模式  TemplateMethod Pattern 问题:创建模型,如何处理更好?有共性有异性,共性放在哪里(abstract)?异性放在哪里(实现)? 缺陷:暴露方法好吗?protected保护起来    方法不会被子类继承修改final更好 概念:模版中的方法(抽象方法.具体方法.钩子方法) 模版模式:重写父类的方法,再调用父类的方法产生不同的结果 具体方法一般体现在调用其他方法的顺序上 模版模式一定是继承来的 2.建造者模式  Builder Pattern 问题升级:继续添

建造者模式(Builder)——从组装电脑开始

建造者模式(Builder)--从组装电脑开始 建造者模式概括起来就是将不同独立的组件按照一定的条件组合起来构成一个相对业务完整的对象.调用者无需知道构造的过程. 我们从组装电脑开始 让我们从买组装电脑开始吧. 首先要买一个电脑,一般都有两个选择 -- 品牌电脑和组装电脑,一般人为了省事和放心都会选择买品牌电脑(也就是整机).在这里,为了更好的分析问题,假定我们为了性价比决定要买组装电脑.那么我们该怎么做呢. 首先我们得学习一个完整的电脑的组成部分有哪些? 经过翻查一部分资料发现,主要部件分为主

菜鸟学设计模式系列笔记之建造者模式(Builder模式)

提供一种"封装机制"来隔离出"复杂对象的各个部分"的变化. 从而保持系统中的"稳定构建算法"不随需求变化而变化.----建造者模式 建造模式是对象的创建模式 建造模式可以将一个产品的内部表象与产品的生成过程分割开来, 从而可以是一个建造过程生成具有不同的内部表象的产品对象. Intent : 将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 Motivation: 在复杂对象的构造过程中,允许同样的构造过程能够加入新的被

设计模式之建造者模式——Builder

一.概述 Builder模式,中文名为建造者模式,又名生成器模式.构建者模式等,是创建型设计模式之一.用于将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 1.适用性: 对象的创建比较复杂.有多种创建形式时 创建复杂对象的算法与对象内部组成和装配是相对独立的 2.UML类图 Builder:定义创建Product各个部件的抽象接口 ConcreteBuilder:继承自Builder,实现创建具体类型的Product所有部件的接口,并提供一个获取最终产品的接口. Dir