设计模式之三种工厂模式与实例详解
来源:互联网 发布:iphone4移动数据开关 编辑:程序博客网 时间:2024/05/23 02:14
这两天学习了下设计模式中的工厂模式,写个总结方便以后记忆和查看。
工厂模式包括:简单工厂模式、工厂方法模式和抽象工厂模式,其中简单工厂模式不是23种标准的设计模式
并且简单工厂模式也没有遵循开闭原则,抽象工厂模式在每一个系列的子系列中符合开闭原则,整个系列不符合,
下面将通过实例分别来讲解三种设计模式
是简单工厂模式的核心,它负责实现创建所有工厂实例的内部逻辑。工厂类可以被外界直接调用,创建用户需要的产品对象
抽象产品角色:
是简单工厂模式所有创建对象的父类,它负责描述所有实例所共有的公共接口
具体产品角色:
是简单工厂模式的创建目标。所有创建的对象都是充当这个角色的某个具体类的实例
还需要在工厂类中增加创建的条件。
负责描述所有工厂的公共接口
具体工厂角色:
重定义工厂方法,返回一个具体产品的实例
抽象产品角色:
所有具体产品创建对象的父类,它负责描述所有实例所共有的公共接口
具体产品角色:
是简单工厂模式的创建目标。所有创建的对象都是充当这个角色的某个具体类的实例
当一个类希望由它的子类来指定它所创建的对象的时候
负责描述所有工厂的公共接口
具体工厂角色:
重定义工厂方法,返回一个具体产品的实例
抽象产品角色:
所有具体产品创建对象的父类,它负责描述所有实例所共有的公共接口
具体产品角色:
是简单工厂模式的创建目标。所有创建的对象都是充当这个角色的某个具体类的实例
客户:
仅仅使用由抽象工厂和抽象产品类声明的方法
一个系统要由多个产品系列中的一个来配置时
当你要强调一系列相关的产品对象的设计以便进行联合使用时
当你提供一个产品类库,而只想显示它的接口而不是实现
工厂模式包括:简单工厂模式、工厂方法模式和抽象工厂模式,其中简单工厂模式不是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;}
补充:
当用抽象工厂新增加一个系列时,只需要创建一个产品具体类和产品系列工厂,
这符合开闭原则,当需要增加一款产品时,则需要改动原来的代码,则不符合开闭原则,
因此其每一个系列的子系列中符合开闭原则,整个系列不符合
总结:
通过上面三种工厂模式可以看出,每种模式都有适用的场景,实现起来大致相同。特别是工厂方法和抽象工厂,他们侧重的点不同,一个是产品,一个是一系列的产品,并且抽象工厂也经常使用工厂方法来实现。阅读全文
1 0
- 设计模式之三种工厂模式与实例详解
- 设计模式之三种工厂模式
- 设计模式之三种工厂模式
- 设计模式之三种工厂模式
- 设计模式之---三种工厂模式
- 设计模式之三工厂
- 【设计模式】之三工厂
- 【设计模式之三工厂】
- 设计模式之三工厂
- 设计模式之工厂模式(三)之抽象工厂模式
- 三 设计模式之抽象工厂模式
- 设计模式之三--抽象工厂模式
- 设计模式之 工厂模式三姐妹
- 设计模式之三:抽象工厂模式
- 设计模式之三 工厂模式
- 设计模式之三抽象工厂模式
- 设计模式之三:抽象工厂模式
- 设计模式之三:抽象工厂模式
- Spring boot之拦截器的实现
- Java基础7:集合类常见面试题
- js debug
- [SDOI2011]计算器 BSGS
- HDU 3061 Battle(最大权闭合图)
- 设计模式之三种工厂模式与实例详解
- 电商营销方式抢购,秒杀Redis原子减decr方法作为剩余库存判断条件的实现方式(1)
- Java 8 之 行为参数化
- Scrapy 命令的使用之一:全局命令
- inner join,left join和right join 的区别
- (noip 2015 斗地主)<搜索+贪心>
- 图形学(2)光栅图形学的直线绘制(上)
- ES6:解构赋值
- 2018京东前端笔试题笔试题