一、序言
系列博客文章都是研读Gof的Design
Patterns这本书的总结分享,书上的有些例子代码不是很全,这边依葫芦画瓢还原了一些代码,可供运行。目前,网络上很多分享设计模式内容的博客文章,都很经典,其中有个CSDN中的设计模式博客专栏也是研究的Gof的书籍,通俗易懂,让读者对设计模式一目了然。自己在学习设计模式的过程中,有时候理解一个设计模式挺简单的,但是想要记住它,运用它,往往比较困难,所以系列文章的主要目的就是让设计模式不单单只是以一个软件模式存在于我们的认知中。更多的是想让读者包括我自己在心中织起一张设计模式的网络,更加体系化,在以后的面向对象的编程中,能够熟练地运用,在设计架构时能够信手拈来,多方面评估不同设计模式的优异性。一些基本的设计模式的定义及何时使用恰当这边不多赘述,这是CSDN博客专栏的网址,大家可以前往学习:
http://blog.csdn.net/wuzhekai1985/article/category/859763
另外系列博客文章以C++语言基础,以一个小的项目讲述同一类型的设计模式,学习的步骤基本是一步一步了解一个小项目时如何构成的,学习的过程中,设计模式的代入感并不会很强,当整个代码浏览完毕,设计模式才会体现出来,摆脱一种带着“就是这种设计模式”的套路去学习设计模式。java的话提供了一些API,我认为少了一点豁然开朗的感觉,用纯C++标准库开发,让人兴奋。
以上只是鄙人愚见,欢迎各路大神赐教。
二、抽象工厂模式
这边以Gof书上创建迷宫的系列例子来展开说明抽象工厂模式,创建型模式将都会用到这一套代码,代码后面会在Github上托管。
创建一个迷宫吧,定义一个迷宫基类MapSiteBase,迷宫的组成Room,Door,Wall等都会继承它:
class MapSiteBase
{
public:
MapSiteBase(){
cout<<"mapsite base."<<endl;
}
virtual ~MapSiteBase(){}//虚析构函数,保险
virtual void Enter() = 0;//为子类定义统一接口,派生类需要实现它
};
接下来是各个组成的定义,类当中的一些成员函数没有特别的去实现,大多数默认为空少数提供打印显示,主要是为了展示设计模式:
class Room : public MapSiteBase
{
public:
Room(int roomNo){}
~Room(){}
virtual void Enter(){}
private:
int _roomNo;
};
class Door : public MapSiteBase
{
public:
Door(Room* = 0,Room* = 0){}//一面墙紧挨着两个房间
virtual void Enter(){}
private:
Room* _romm1;
Room* _romm2;
};
class Wall : public MapSiteBase
{
public:
Wall(){}
virtual void Enter(){}
};
以上是三个组件的简单类定义,组件构成迷宫,简单说wall & door 构成 room,一些列room构成迷宫,需要定义一个迷宫类:
class Maze
{
public:
Maze(){}
void addRoom(Room*){}//往迷宫中添加Room
Room* RoomNo(int) const{}
};
迷宫的基本组件都定义完毕,接下里就是构建过程,定义一个迷宫构建类,简单说是时候写一个迷宫游戏了:
class MazeGame
{
public:
MazeGame(){}
virtual ~MazeGame(){}
virtual Maze* createMaze(MazeFactory &factory);//创建迷宫的方法
virtual Maze* createMaze(MazeBuilder &builder);//可忽略,builder中用到
};
由上面可以看到这个时候去实现Maze中的createMaze这个成员函数就可以构造迷宫了,仔细想想,最简单暴力的就是直接在这个成员函数中new Room、Door、Wall,然后一一组合制定之间的关系,构成一个复杂的迷宫。但是万一需要改变一下迷宫的规则或者添加一些特性比如施有魔法的迷宫等,就要重新对这个成员函数进行编码了。疑问先晾在这,后面自会明朗。
为了让createMaze变得更加灵活,减少编码,定义一个可扩张的创建迷宫游戏的类:
class MazeFactory
{
public:
MazeFactory(){}
virtual ~MazeFactory(){}
virtual Maze* makeMaze() const//成员函数都默认实现创建普通的迷宫,定义为virtual为了派生类实现他们感兴趣的方法
{
return new Maze();//立即返回
}
virtual Wall* makeWall()