设计模式之三种工厂模式与实例详解

版权声明:本文为博主原创文章,如若转载请注明本人原始地址。 https://blog.csdn.net/Andy_93/article/details/77900773
这两天学习了下设计模式中的工厂模式,写个总结方便以后记忆和查看。
工厂模式包括:简单工厂模式、工厂方法模式和抽象工厂模式,其中简单工厂模式不是23种标准的设计模式 
并且简单工厂模式也没有遵循开闭原则,抽象工厂模式在每一个系列的子系列中符合开闭原则,整个系列不符合,
下面将通过实例分别来讲解三种设计模式

一 简单工厂模式

参与者:

工厂角色:
是简单工厂模式的核心,它负责实现创建所有工厂实例的内部逻辑。工厂类可以被外界直接调用,创建用户需要的产品对象
抽象产品角色:
是简单工厂模式所有创建对象的父类,它负责描述所有实例所共有的公共接口
具体产品角色:
是简单工厂模式的创建目标。所有创建的对象都是充当这个角色的某个具体类的实例

适用性:

工厂类负责创建的对象比较少时

客户只关心传入工厂类的参数,对于如何创建对象(逻辑)不关心

实例:

#include "stdafx.h" #include <iostream> #include <assert.h> using namespace std; //抽象产品角色 class CFruit { public: virtual void sayName() = 0; }; //具体产品角色 芒果类 class CMango : public CFruit { public: virtual void sayName() { cout << "I am a Mango" << endl; } }; //具体产品角色 苹果类 class CApple : public CFruit { public: virtual void sayName() { cout << "I am a Apple" << endl; } }; //工厂角色 class CFactory { public: CFruit* create(const char const * p) { if (strcmp(p, "mango") == 0) { return new CMango(); } else if (strcmp(p, "apple") == 0) { return new CApple(); } else { return NULL; } } }; int main(int argc, char* argv[]) { printf("start!!\n"); system("pause"); CFactory* factory = new CFactory(); CFruit* pMango = factory->create("mango"); assert(pMango != NULL); pMango->sayName(); system("pause"); CFruit* pApple= factory->create("apple"); assert(pApple != NULL); pApple->sayName(); system("pause"); delete factory; factory = NULL; delete pMango; pMango = NULL; delete pApple; pApple = NULL; return 0; }

补充:

在简单工厂模式中,如果我们需要重新增加一种水果,比如香蕉,那么我们不仅仅需要增加一个CBanana类,
还需要在工厂类中增加创建的条件。

二 工厂方法模式

参与者:

抽象工厂角色:
负责描述所有工厂的公共接口
具体工厂角色:
重定义工厂方法,返回一个具体产品的实例
抽象产品角色:
所有具体产品创建对象的父类,它负责描述所有实例所共有的公共接口
具体产品角色:
是简单工厂模式的创建目标。所有创建的对象都是充当这个角色的某个具体类的实例

适用性:

当一个类不知道它锁不许创建的对象的类的时候
当一个类希望由它的子类来指定它所创建的对象的时候

实例:

//抽象产品角色 class CFruit { public: virtual void sayName() = 0; }; //具体产品角色 芒果类 class CMango : public CFruit { public: virtual void sayName() { cout << "I am a Mango" << endl; } }; //具体产品角色 苹果类 class CApple : public CFruit { public: virtual void sayName() { cout << "I am a Apple" << endl; } }; //抽象工厂角色 class CFactory { public: virtual CFruit* create() = 0; }; //具体工厂角色 芒果工厂类 class CMangoFactory : public CFactory { public: CFruit* create() { return new CMango(); } }; //具体工厂角色 苹果工厂类 class CAppleFactory : public CFactory { public: CFruit* create() { return new CApple(); } }; int main(int argc, char* argv[]) { printf("start!!\n"); system("pause"); CMangoFactory* pMangoFac = new CMangoFactory(); CFruit* pMango = pMangoFac->create(); pMango->sayName(); system("pause"); CAppleFactory* pAppleFac = new CAppleFactory(); CFruit* pApple = pAppleFac->create(); pApple->sayName(); system("pause"); delete pMangoFac; pMangoFac = NULL; delete pMango; pMango = NULL; delete pAppleFac; pAppleFac = NULL; delete pApple; pApple = NULL; return 0; }

补充:

当抽象方法模式中需要新增一种水果类型,如香蕉时,只需要新增一个香蕉类,一个香蕉工厂即可,并不会影响其原有代码。因此其遵循开闭原则。

三 抽象工厂模式

参与者:

抽象工厂角色:
负责描述所有工厂的公共接口
具体工厂角色:
重定义工厂方法,返回一个具体产品的实例
抽象产品角色:
所有具体产品创建对象的父类,它负责描述所有实例所共有的公共接口
具体产品角色:
是简单工厂模式的创建目标。所有创建的对象都是充当这个角色的某个具体类的实例
客户:
仅仅使用由抽象工厂和抽象产品类声明的方法

适用性:

一个系统要独立于它的产品的创建、组合和表示时
一个系统要由多个产品系列中的一个来配置时
当你要强调一系列相关的产品对象的设计以便进行联合使用时
当你提供一个产品类库,而只想显示它的接口而不是实现

 
 

实例:

//抽象产品角色 class CFruit { public: virtual void sayName() = 0; }; //具体产品角色 本地芒果类 class CLocalMango : public CFruit { public: virtual void sayName() { cout << "I am a local Mango" << endl; } }; //具体产品角色 本地苹果类 class CLocalApple : public CFruit { public: virtual void sayName() { cout << "I am a local Apple" << endl; } }; //具体产品角色 外地芒果类 class CFieldMango : public CFruit { public: virtual void sayName() { cout << "I am a Field Mango" << endl; } }; //具体产品角色 外地苹果类 class CFieldApple : public CFruit { public: virtual void sayName() { cout << "I am a Field Apple" << endl; } }; //抽象工厂角色 class CFactory { public: virtual CFruit* createMango() = 0; virtual CFruit* createApple() = 0; }; //具体工厂角色 本地水果工厂类 class CLocalFruitFactory : public CFactory { public: CFruit* createMango() { return new CLocalMango(); } CFruit* createApple() { return new CLocalApple(); } }; //具体工厂角色 外地水果工厂类 class CFieldFruitFactory : public CFactory { public: CFruit* createMango() { return new CFieldMango(); } CFruit* createApple() { return new CFieldApple(); } }; int main(int argc, char* argv[]) { printf("start !!\n"); system("pause"); CLocalFruitFactory* pLocalfac = new CLocalFruitFactory(); CFruit* pLocalApple = pLocalfac->createApple(); pLocalApple->sayName(); system("pause"); CFruit* pLocalMango = pLocalfac->createMango(); pLocalMango->sayName(); system("pause"); CFieldFruitFactory* pFieldfac = new CFieldFruitFactory(); CFruit* pFiledApple = pFieldfac->createApple(); pFiledApple->sayName(); system("pause"); CFruit* pFieldlMango = pFieldfac->createMango(); pFieldlMango->sayName(); system("pause"); delete pLocalfac; pLocalfac = NULL; delete pLocalApple; pLocalApple = NULL; delete pLocalMango; pLocalMango = NULL; delete pFieldfac; pFieldfac = NULL; delete pFiledApple; pFiledApple = NULL; delete pFieldlMango; pFieldlMango = NULL; return 0; }

补充:

  当用抽象工厂新增加一个系列时,只需要创建一个产品具体类和产品系列工厂,
 这符合开闭原则,当需要增加一款产品时,则需要改动原来的代码,则不符合开闭原则,
 因此其每一个系列的子系列中符合开闭原则,整个系列不符合

总结:  

通过上面三种工厂模式可以看出,每种模式都有适用的场景,实现起来大致相同。特别是工厂方法和抽象工厂,他们侧重的点不同,一个是产品,一个是一系列的产品,并且抽象工厂也经常使用工厂方法来实现。

猜你喜欢

转载自blog.csdn.net/Andy_93/article/details/77900773