1.1 BUILDER生成器
1、 意图
将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。
构建是通过对生成器抽象接口的调用实现的。而构建出来的产品的类型(表示),是由具体的进行构建的生成器的子类的实例来决定的。这样导向器只需要调用生成器的抽象接口生成产品,而具体生成什么样的产品,则是根据导向器配置的具体的生成器实例相关。
终于理解了它是如何把复杂对象的构建和它的表示分离的,也理解了为什么同样的构建过程。
2、 动机
3、 适用性
当创建复杂对象的算法应该独立于该对象的组成以及他们的装配方式时——对象的组成及装配方式是生成器的抽象接口来表示的。而对象的创建的算法是有生成器的子类实现的。
当构造过程必须允许被构造的对象有不同的表示时——也就是,同样的构造过程,可以生成不同的产品。这里是通过配置导向器的生成器的子类实例来实现的。
4、 结构
5、 参与者
l Builder:为创建一个product对象的各个部件指定抽象接口。这些部件最终构成了product,而对这些抽象接口的调用,则是装配product的操作,调用的次数,入参等不同,则最终生成的product也不同。product本身的构造过程可能会非常复杂。但是,这些复杂度对Director(导向者)是隐藏的。这些抽象的接口描述了产品的组成以及装配方式。
l ConcreteBuilder:实现Builder的接口以构造和装配产品的各个部件;定义并明确它所创建的表示;提供一个检索产品的接口。这个类实现了Builder的抽象接口,从而可以创建不同的表示,但是组成和装配过程还是一样的。
l Director:构造一个使用Builder抽象接口的对象。更对象根据Builder的接口来装配并生产产品。
l Product:表示被构造的复杂的对象。ConcreteBuilder创建该产品的内部表示,并定义它的装配过程;包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
6、 协作
l 客户创建Director对象,并用它想要的Builder对象进行配置。
l 一旦产品不仅被生成,导向器就会通知生成器。
l 生成器处理导向器请求,并且将部件添加到该产品中。
l 客户从生成器中检索产品。
7、 效果
l 它使你可以改变一个产品的内部表示。Builder提供给Director的抽象接口可以使生成器隐藏这个产品的表示和内部结构。它同时也隐藏了该产品时如何装配的。因为产品时通过抽象接口构造的,你改变该产品的内部表示时,所要做的只是定义一个新的生成器。
l 它将构造代码和表示代码分开。Builder模式通过封装一个复杂对象的创建和表示方式提高了对象的模块性。每个ConcreteBuilder包含了创建和装配一个特定产品的所有代码。
l 它可以使你对构造过程进行更精细的控制。
8、 实现
l 通常一个抽象的Builder类为导向者可能要求创建的每一个构件定义一个操作。这些操作缺省什么也不做。一个ConcreteBuilder类对它有兴趣创建的构建重定义这些操作。
l 装配和构造接口:一般构造请求的结果只是被添加到产品中,特殊情况下,需要返回给导向器。
l 产品没有抽象类:一般他们没有公共的部分。如果有也可以设置一个抽象类。
l Builder中缺省的方法为空。
9、 代码示例
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();
};//MazeBuilder是生成器
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;
};//StandardMazeBuilder是ConcreteBuilder,提供部件的具体构造代码
Maze* MazeGame::CreateMaze (MazeBuilder& builder) {
builder.BuildMaze();
builder.BuildRoom(1);
builder.BuildRoom(2);
builder.BuildDoor(1, 2);
return builder.GetMaze();
}//CreateMaze是导向器,调用生成器的抽象接口完成产品的构造过程。
//下面代码描述产品的构造过程
Maze* maze;//最终的产品
MazeGame game;//Director,导航者
StandardMazeBuilder builder;//ConcreteBuilder,实际的构造类
game.CreateMaze(builder);//开始装配
maze = builder.GetMaze();//获取装配后的产品