大话设计模式C++版——表驱动法改造简单工厂
上回《大话设计模式C++版——简单工厂模式》中指出了简单工厂模式的缺陷,即违背了开发—封闭原则,其主要原因是由于switch的判断结构的使用,使修改或添加新的对象时需要改动简单工厂类的代码,如何改造switch结构,表驱动法就可以粉墨登场了。
表驱动法的介绍见《数据驱动编程之表驱动法》。
1、面向接口编程,先改造抽象接口类IOperation
class IOperation
{
public:
IOperation() : m_nNuml(0), m_nNumr(0) {}
virtual ~IOperation() {} virtual void SetNum(int nNuml = 0, int nNumr = 0)
{
m_nNuml = nNuml;
m_nNumr = nNumr;
} virtual int CalculateResult() = 0; public:
typedef IOperation* (CALLBACK* fn_CreateObject)(); protected:
int m_nNuml, m_nNumr;
};
接口基本无改动,由于表驱动法中需要在表中填入驱动函数接口,故先定义一个该接口函数的定义,用于产生具体接口对象。
2、改造接口对象类
class COperation_Add : public IOperation
{
public:
int CalculateResult()
{
return m_nNuml + m_nNumr;
} static IOperation* CALLBACK CreateObject()
{
return new COperation_Add();
}
}; class COperation_Dec : public IOperation
{
public:
int CalculateResult()
{
return m_nNuml - m_nNumr;
} static IOperation* CALLBACK CreateObject()
{
return new COperation_Dec();
}
};
增加了CreateObject()静态函数,改函数的作用是用来产生本对象。由于表驱动函数是用于回调的,所以需要定义为静态回调函数。
3、改造工厂类,增加驱动表改造switch结构(重点)
class CClassFactory
{
public:
CClassFactory() {}
virtual ~CClassFactory() {} BOOL AddOperationFunc(char cOperation, IOperation::fn_CreateObject func)
{
if (func)
{
m_mapOperationFunc[cOperation] = func;
return TRUE;
} return FALSE;
} IOperation* CreateObject(char cOperation)
{
IOperation::fn_CreateObject func = m_mapOperationFunc[cOperation]; if (func)
{
return func();
} return NULL;
} protected:
std::map<char, IOperation::fn_CreateObject> m_mapOperationFunc; //用map实现驱动表
};
工厂类中的switch消失了,换成了在map中以操作符为key找对应驱动函数,然后进行调用。同时增加了添加新操作符和对应驱动函数的接口AddOperationFunc(),这样如果需要新增加对象或者修改操作符对应的驱动函数,调用此接口即可,灵活性大大增加。
4、使用示例
void Test()
{
CClassFactory oCClassFactory;
IOperation* poIOperation = NULL; //添加对象工厂的生产对象
oCClassFactory.AddOperationFunc('+', COperation_Add::CreateObject);
oCClassFactory.AddOperationFunc('-', COperation_Dec::CreateObject); poIOperation = oCClassFactory.CreateObject('+'); if (poIOperation)
{
poIOperation->SetNum(2, 3);
printf("2 + 3 = %d\n", poIOperation->CalculateResult()); delete poIOperation;
} poIOperation = oCClassFactory.CreateObject('-'); if (poIOperation)
{
poIOperation->SetNum(2, 3);
printf("2 + 3 = %d\n", poIOperation->CalculateResult()); delete poIOperation;
}
}
使用前需添加操作符和对应的驱动函数,这样一来将用户的任务加重了,而且需要用户认识的类增加了,封装性降低了。是否可进一步改进?
5、进一步改进简单工厂类,提高封装性
class CNewClassFactory : CClassFactory
{
public:
virtual ~CNewClassFactory() {} virtual void Init()
{
AddOperationFunc('+', COperation_Add::CreateObject);
AddOperationFunc('-', COperation_Dec::CreateObject);
}
};
新简单工厂类中,增加了一个初始化函数Init(),代替用户的进行操作符和对应的驱动函数,这样用户只需要调用Init()函数即可,封装性进一步提高,那么有同学可能会问,如果要增加新的计算对象,还不得改动Init()函数代码,这不跑了一圈又回到没改造前的原点了。
这就得用到开放—封闭原则了,新简单工厂类CNewClassFactory中,我们将Init()函数申明为虚函数了,如果我们要增加新的计算对象,可以有2个途径:
5.1用户在自己代码中调用AddOperationFunc()函数进行添加。
5.2继承新简单工厂类,重写Init()函数。
大话设计模式C++版——表驱动法改造简单工厂的更多相关文章
- 大话设计模式C++实现-第1章-简单工厂模式
一.UML图 二.包括的角色 简单工厂模式包括三个角色: (1)工厂类Factory:工厂类是用来制造产品的. 因此,在Factory中有一个用于制造产品的Create函数或者Generate函数之类 ...
- 大话设计模式C++版——简单工厂模式
简单工厂模式应该是所有设计模式中最简单,也最基础的一种模式,以下是一个简单的采用工厂模式写一个加减法的计算器. 1.抽象接口类——依赖倒转原则(高层和底层都要依赖于抽象,针对接口编程) class I ...
- 大话设计模式C++版——工厂模式在COM中的典型应用
上篇<大话设计模式C++版——抽象工厂模式>中,我们拯救世界未遂,留下小小的遗憾,本篇中我们将给出一个解决方案——COM组件技术,同时也顺便扯扯工厂模式在COM组件技术中的应用. 工厂模式 ...
- 大话设计模式C++版——抽象工厂模式
前面说过,简单工厂模式是最基础的一种设计模式,那以工厂命名的设计模式就是23种设计模式中最多的一种,他们一脉相承,一步一步进化而来,这里就是其中的最后一种——抽象工厂模式(Abstract Facto ...
- 大话设计模式C++版——代理模式
本篇开始前先发个福利,程杰的<大话设计模式>一书高清电子版(带目录)已上传至CSDN,免积分下载. 下载地址:http://download.csdn.net/detail/gufeng9 ...
- 大话设计模式C++版——工厂方法模式
工厂方法模式是以简单工厂模式为基础的,如果未了解简单工厂模式的同学可先浏览<大话设计模式C++版——简单工厂模式>.在简单工厂模式中,提到过简单工厂模式的缺陷,即违背了开发—封闭原则,其主 ...
- Design Patterns Simplified - Part 3 (Simple Factory)【设计模式简述--第三部分(简单工厂)】
原文链接:http://www.c-sharpcorner.com/UploadFile/19b1bd/design-patterns-simplified-part3-factory/ Design ...
- 设计模式在cocos2d-x中的使用--简单工厂模式(Simple Factory)
什么是简单工厂模式? 从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式.通过专门定义一个类来负责创建其它类的实例,被创建的实例 ...
- 大话设计模式C++版——原则和引言
转贴请注明转自:http://blog.csdn.net/gufeng99/article/details/45832711 读程杰的<大话设计模式>有一段时间了,将其C#版的设计模式代码 ...
随机推荐
- SQL Server 事务
from :http://www.cnblogs.com/kissdodog/p/3169788.html 事务全部是关于原子性的.原子性的概念是指可以把一些事情当做一个单元来看待.从数据库的角度看, ...
- UML类图关系总结
在UML类图中,常见的有以下几种关系: 泛化(Generalization) 实现(Realization) 关联(Association) 聚合(Aggregation) 组合(Compositio ...
- angular学习的一些小笔记(中)之ng-init
ng-init是给angular执行给定的表达式,初始化变量的值 <!DOCTYPE html> <html> <head> <meta charset='U ...
- Hexo - 快速,轻量,强大的 Node.js 博客框架
Hexo 是一个快速,轻量,强大的 Node.js 博客框架.带给你难以置信的编译速度,瞬间生成静态文件:支持 Markdown,甚至可以在 Hexo 中集合 Octopress 插件:只需要一个命令 ...
- 【zepto学习笔记01】核心方法$()(补)
前言 昨天学习了核心$(),有几个遗留问题,我们今天来看看吧 $.each 遍历数组/对象,将每条数据作为callback的上下文,并传入数据以及数据的索引进行处理,如果其中一条数据的处理结果明确返回 ...
- sharepoint 开发相关工具总结
1.CAML Designer 2013 开发caml用 http://biwug-web.sharepoint.com/SitePages/Caml_designer.aspx 2.SharePoi ...
- 获取设备的mac地址可靠的方法
参考自:http://www.open-open.com/lib/view/open1433406847322.html /** * 获取设备的mac地址 * * @param ac * @param ...
- html框架—多对话框(相同id)处理
一个网站的数据大多数都是异步刷新的,这没什么好说的,然后现在很多前后端框架,大家都知道框架很好用,不用自己写样式,只要利用框架上的语法就能做出漂亮的动态的效果来,而用框架的话大多数的动态效果都是动态生 ...
- 【代码笔记】iOS-传身份证号码可返回生日字符串
代码: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. NS ...
- OC 初识NSString,self关键字,继承,成员变量的可见性,description方法
OC 初识NSString,self关键字,继承,成员变量的可见性,description方法 初识 NSString: char * string = "旭宝爱吃鱼"; 常量字符 ...