Builder的中文名:生成器
作用
GOF中的描述:将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的标识。
描述的解释:Builder,按名字理解是建造,那么建造什么呢?那造房子来说,房子的组成主要是砖头、钢筋、水泥。而且其建造的构建基本一致,先打地基,再修承重柱,接着是封墙面,一步步稳扎稳打。不同的可能是不同材料混合的比例、钢筋的材质等等。于是,可以从中固化出一套造房子的基本步骤,即GOF中所说的复杂对象的构建;相对于不同材料的混合方法,即表示方法,进行分析。
- 主要目的:将一个个的组件,组合成一个可以使用的产品。比如拿零件组装出一辆汽车。
- 组件的生成方法都集中在一个抽象类中
- 产品的产出由生产的“工厂”决定
优缺点
- 通过抽象接口,通过改变内在实现,但不影响外部使用;
- 工厂可以决定组件的组装方式,来产出不同的产品;
- 和抽象工厂(Abstract Factory)一样,对修改的开放性差,要对抽象接口增加新的方法,支持不友好;
结构
- Builder负责产生组件的抽象方法;
- Director负责产品的生产;
- ConcreteBuilder负责对产品进制实际的组装;
例子
以上图为例,Director指代MazeGame类,Builder指代MazeBuilder,ConcreteBuidler指代MazeBuilderStandard类,Product指代Maze类,即Maze为生产结束后返回的产品。
#pragma once
class Room {
public:
Room(int n) { }
};
class Wall {};
class Door {
public:
Door(Room* r1, Room* r2) {}
};
class Maze {
public:
void AddRoom(Room* r1) {}
Room* RoomNo(int n) { return nullptr; }
};
/
class EnhantedRoom : public Room {
public:
EnhantedRoom(int n) : Room(n) {
}
};
class DoorNeedingSpell : public Door {
public:
DoorNeedingSpell(Room* r1, Room* r2) : Door(r1, r2) { }
};
class BombedWall : public Wall {};
class BombedRoom : public Room {
public:
BombedRoom(int n) : Room(n) {}
};
#pragma once
#include "Maze.h"
class MazeBuilder
{
public:
virtual void BuildeMaze() { }
virtual void BuildeRoom(int n) { }
virtual void BuildeDoor(int r1, int r2) { }
virtual Maze* GetMaze() { return nullptr; }
protected:
MazeBuilder() {}
};
class MazeBuilderStandard : public MazeBuilder
{
public:
virtual void BuildeMaze() {
_currentMaze = new Maze;
}
virtual Maze* GetMaze() { return _currentMaze; }
virtual void BuildeRoom(int n) {
if (!_currentMaze->RoomNo(n))
{
Room* newRoom = new Room(n);
_currentMaze->AddRoom(newRoom);
// 设置room的属性
}
}
virtual void BuildeDoor(int n1, int n2) {
Room* r1 = _currentMaze->RoomNo(n1);
Room* r2 = _currentMaze->RoomNo(n2);
Door* d = new Door(r1, r2);
// 设置room的属性
}
public:
MazeBuilderStandard() {
_currentMaze = 0;
}
Maze* _currentMaze;
};
#pragma once
#include "Maze.h"
#include "Builder.h"
class MazeGame {
public:
MazeGame() {}
Maze* CreateMaze(MazeBuilder& builder)
{
builder.BuildeMaze();
builder.BuildeRoom(1);
builder.BuildeRoom(2);
builder.BuildeDoor(1, 2);
return builder.GetMaze();
}
};
#include "MazeGame.h"
#include "Builder.h"
int main()
{
MazeGame game;
MazeBuilderStandard builder;
game.CreateMaze(builder); // director负责构件的过程
Maze* maze = builder.GetMaze(); // 得到最终的产品
return 1;
}
Github链接 :https://github.com/potterhere/CS-note/tree/master/DesignPattern/CreateMode_Builder
相关模式
Abstract Factory。
抽象工厂模式和生成器模式很接近,都是基于了一个总的抽象基类,但两者所侧重的阶段不同。抽象工厂更侧重于与产品的结合情况,使在使用产品的过程中无感知。而生成器模式主要侧重于产品的产生,只需负责得到最后的一个产品即可。
参考资料
1. 《设计模式:可复用面向对象软件的基础》 GOF
2. 生成器——Youtube