创建型模式初步和Abstract Factory模式的实现

创建型模式抽象实例化过程。帮助一个系统独立于如何创建、组合和表示它的那些对象。

 

以构建一个房间探索游戏的设计为例:

未引入创建型模式前,对于一个完整的探索系统,需要由用户不断地调用各个组件的构造函数,从而代码渐渐复杂起来。代码复杂且未经设计的最大的后果便是维护困难。现在想要给某一套组件换成另外一套组件,带来的后果是所有的用户代码都要进行修改。这个过程是有一定风险的。

解决办法是一定存在的,现在引入几个创建型模式:

传入工厂对象作参数来指定创建房间、墙壁和门的类型:Abstract Factory 抽象工厂
调用虚函数而不是构造函数来创建(让子类来决定实例化那个类):Factory Method 工厂方法
引入传递对象并且通过这个对象增加房间、墙壁和门:Builder 生成器
原型的房间、墙壁和门对象参数化,它拷贝并将这些对象增加到迷宫中:Prototype 原型
对于每一种Factory而言每个程序里仅有一个:Singleton 单例

 

Abstract Factory最擅长解决替换成套组件的问题,它通过传入对象来确定内部实例化的类,取消对类名的硬编码。

请看示意图:

最原始的工厂可以构造PartA PartB。如今使用Part' PartA' PartB'。容易想到使用一个继承的结构。让Part'继承Part,把Part中实例化PartA PartB的函数声明为virtual,从而可以在Part'中重写实例化函数,这样调用时虽然用的还是PartA的名字,但是事实上调用的是PartA'的内容,实现了代码重用。

Client无需了解使用的是PartA0还是PartA1,一切都在构造Factory时使用的是PartFactory还是SpecialPartFactory。

 

代码示例:

#include<stdio.h>

class PartA {
	int len;
public:
	PartA(int n) { len = n; }
	virtual ~PartA() {}
};
class PartA1 : public PartA {
	int len;
	int item;
public:
	PartA1(int n):PartA(n) { len = n; }
};

class PartB {
	int id;
	PartA* rList[100];
public:
	PartB(int i) { id = i; }
	virtual ~PartB() {
		//析构内部内容
	}
};
class PartB1 : public PartB {
	int id;
	int item;
	
public:
	PartB1(int i, int it) :PartB(i) { id = i; item = it; }
};

class Maze {
public:
	Maze() {};
	~Maze() {
		//析构所有Maze内包含的部件
		//最后析构delete maze
	}
private:
	PartB* rlist[100];
};

//Abstract Factory
class MazeFactory {
public:
	MazeFactory(){}
	virtual Maze* MakeMaze() const
	{
		printf("Maze Start!");
		return new Maze;
	};
	virtual PartA* MakePartA(int l) const
	{
		printf("PartA %d!", l);
		return new PartA(l);
	}
	virtual PartB* MakePartB(int i) const
	{
		printf("PartB %d!", i);
		return new PartB(i);
	}
};
class UnexpectedMazeFactory : public MazeFactory {
public:
	UnexpectedMazeFactory() {};
	virtual PartA* MakePartA(int l) const
	{
		printf("Item PartA %d!", l);
		return new PartA(l);
	}
	virtual PartB* MakePartB(int i) const
	{
		printf("Special PartB %d with item %d!", i, GetSpecial());
		return new PartB1(i, GetSpecial());
	}
protected:
	int GetSpecial() const { return 1; }; //返回一个值
};

class Game {
public:
	Maze* CreateMaze(MazeFactory& factory) {
		Maze* myMaze = factory.MakeMaze();
		PartB* r1 = factory.MakePartB(10);
		PartB* r2 = factory.MakePartB(5);
		PartA* a3 = factory.MakePartA(1);
		return myMaze;
	}
private:
	Maze* m;
};

int main() {
	Game myGame;
	UnexpectedMazeFactory factory;
	Maze* myMaze = myGame.CreateMaze(factory);
	getchar();
}

 

参考书籍:《设计模式 可复用面向对象软件的基础》Erich Gamma等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值