1 简介
- 创建型模式抽象了实例化过程。它们帮助一个系统独立于如何创建、组合和表示它的那些对象。
- 根据范围可将创建型模式分为以下两种:
- 类创建型模式:使用***继承***改变被实例化的类;
- 对象创建型模式:将实例化委托给另一个对象。
- 随着系统演化得越来越依赖于对象复合而不是类继承,创建型模式变得更为重要。
2 五种创建型模式
名称 | 类型 |
---|---|
抽象工厂模式(Abstract Factory) | 对象创建型 |
生成器模式(Builder) | 对象创建型 |
工厂方法(Factory Method) | 对象创建型 |
原型模式(Prototype) | 对象创建型 |
单例模式(Singleton) | 对象创建型 |
3 示例程序
由于五种创建型设计模式紧密相关,因此我们将这五种模式放在一起对比研究来突出它们之间的异同。
本文(包括后续博客)中我们将以一个通用的例子(创建一个电脑迷宫游戏)来说明它们的实现。这个迷宫游戏会通过这五种不同的模式来实现部分功能。下面详细介绍这个例子中的一些基础编码内容。
3.1 定义房间的四个方向(enum Direction)
每一个房间有四面,因此我们用枚举类型Direction来指定房间的东西南北四个方向:
enum Direction
{
North,
South,
East,
West
};
3.2 定义迷宫基本组件(MapSite->Room,Wall,Door)
3.2.1 抽象类MapSite
类MapSite是所有迷宫组件的公共抽象类,类中只定义了一个操作Enter,这个操作可以触发两种结果:
- 如果门是开着的,那么你会进入另一个房间;
- 如果门是关着的,那么你会碰壁。
class MapSite
{
public:
virtual void Enter() = 0;
};
3.2.2 具体类Room(MapSite派生类)
class Room : public MapSite
{
public:
Room(int roomNo);
virtual void Enter();
MapSite* GetSide(Direction) const;
void SetSide(Direction, MapSite*);
private:
MapSite* m_Sides[4]; // 四个方向的组件
int m_RoomNumber; // 房间号,用于标识迷宫中的房间
};
3.2.3 具体类Wall(MapSite派生类)
class Wall : public MapSite
{
public:
Wall();
virtual void Enter();
};
3.2.4 具体类Door(MapSite派生类)
class Door : public MapSite
{
public:
Door(Room *r1 = nullptr, Room *r2 = nullptr);
virtual void Enter();
Room* OtherSideFrom(Room *);
private:
Room *m_Room1;
Room *m_Room2;
bool m_IsOpen;
};
3.3 定义房间集合Maze类
Maze类用来存放所有加入迷宫的房间集合,通过房间号(RoomNo)可以找到集合中对应的房间。
class Maze
{
public:
Maze();
void AddRoom(Room*);
Room* RoomNo(int) const;
private:
std::map<int, Room*> m_RoomCollection;
};
3.4 定义迷宫游戏MazeGame类
MazeGame类用于创建迷宫,一个简单直接的创建迷宫的方法是使用一系列操作将构件增加到迷宫中,然后连接它们。
例如,下面的成员函数将创建一个迷宫,这个迷宫由两个房间和它们之间的一扇门组成:
Maze* MazeGame::CreateMaze()
{
Maze *aMaze = new Maze();
Room *r1 = new Room(1);
Room *r2 = new Room(2);
Door *theDoor = new Door(r1, r2);
aMaze->AddRoom(r1);
aMaze->AddRoom(r2);
r1->SetSide(North, new Wall());
r1->SetSide(East, theDoor);
r1->SetSide(South, new Wall());
r1->SetSide(West, new Wall());
r2->SetSide(North, new Wall());
r2->SetSide(East, new Wall());
r2->SetSide(South, new Wall());
r2->SetSide(West, theDoor);
return aMaze;
};
这种实现方法依然过于复杂,显然我们可以通过创建型模式让它变得更简单和灵活。具体实现方法将在后续的博客中体现。
4 参考资料
[1]《设计模式:可复用面向对象软件的基础》
[2]《大话设计模式》