当前位置: 代码迷 >> 综合 >> 设计模式(一) 工厂方法 和 抽象工厂
  详细解决方案

设计模式(一) 工厂方法 和 抽象工厂

热度:14   发布时间:2023-11-02 18:13:58.0

其实工厂方法和抽象工厂是两个设计模式,之所以将它两放在一起是因为它两非常相似,都是解决对象创建这一类的问题。

工厂,就是利用c++动态多态的机制(虚函数,静态多态是继承),将对象的具体创建也就是new的部分延迟到一个小黑屋里面。

抽象工厂是在工厂方法的基础上进行的扩展,所以我们先了解什么是工厂方法。

 

工厂方法,在这里我们举一个例子,我们要创建一个英灵,英灵又有好多种类的,比如Archer,Berserker,Assassin,等等。

很显然,我们能够写出如下代码:

class Zero
{
public:virtual ~Zero(){};virtual void born() = 0;
};class Archer : public Zero
{
public:~Archer();virtual void born(){//red A}
};class BerserKer : public Zero
{
public:~BerserKer();virtual void born(){//protect servant}
};class Assissan : public Zero
{
public:~Assissan();virtual void born(){//assassinate}
};

在调用时,比如我们要召唤红A的话,一般我们都会这么写:

Zero* zero = new Archer();
zero->born();

这样写看起来没什么问题,但是这样写耦合度高,不符合高聚合低耦合的C++面向对象的原则。

!会包含子类的头文件,会产生编译时依赖!

运用工厂方法,我们可以定义一个factory类来创建并返回这个对象:

class ZeroFactory
{
public:virtual ~ZeroFactory();virtual Zero* createZero() = 0;
};

这样我们就可以为每一个职介的英灵都创建一个工厂:

class ArcherFactory : public ZeroFactory
{
public:virtual ~ArcherFactory(){};virtual Zero* createZero(){return new Archer;}
};class BerserKerFactory : public ZeroFactory
{
public:virtual ~BerserKerFactory(){};virtual Zero* createZero(){return new BerserKer;}
};class AssissanFactory : public ZeroFactory
{
public:virtual ~AssissanFactory(){};virtual Zero* createZero(){return new Assissan;}
};

当然,这里我只是将他们写在一起了,实际情况它们一般都不在一个cpp里面,并且有一种大多数的做法就是在程序起来的时候,将每个factory都保存一个实例放在一个map中管理起来,这个之后再说。

这样我们只用传递一个factory的指针就能创建对应的Zero。

缺点:要求创建英灵的方法/参数相同(都是一个servant)。

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

抽象工厂方法。

应对“多系列对象的创建”,即创建的多个对象之间存在相互依赖,或作用的关系,并且不同系列的对象不能相互依赖。

缺点:难以应对“新对象的需求变动”。

这样看起来好像比较难以理解。

还是举一个例子:

为了召唤英灵,我们首先需要一个servant,还需要一个仪式,并且一个servant只能通过一种特定仪式创建一种英灵。

比如士郎就只能创建saber。

用工厂方法写的话,这里servant需要一个工厂,仪式也需要一个工厂,代码如下(只举一个子类):

class Servant
{};class ling : public Servant
{};class ServantFactory
{virtual Servant* createSerVant();
};class lingFactory : public ServantFactory
{virtual Servant* createSerVant(){new ling;}
};

这只是servant的工厂,还有仪式的没写。。。

这样看起来就有点臃肿了。

因为这一套是关联的,所以我们可以将servant的创建和仪式的创建放到一个工厂里面。

class FateZeroFactory
{virtual Servant* createSerVant() = 0;virtual Rite* createRite() = 0;
};

呃就这样了。。。

  相关解决方案