大话设计模式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()函数。


 

转载于:https://www.cnblogs.com/organic/p/5005647.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
0.基础的基础 |-学习WIN64驱动开发的硬件准备 |-配置驱动开发环境 ------------------------------ 1.驱动级HelloWorld |-配置驱动测试环境 |-编译和加载内核HelloWorld ------------------------------ 2.内核编程基础 |-WIN64内核编程的基本规则 |-驱动程序与应用程序通信 |-内核里使用内存 |-内核里操作字符串 |-内核里操作文件 |-内核里操作注册 |-内核里操作进线程 |-驱动里的其它常用代码 ------------------------------ 3.内核HOOK与UNHOOK |-系统调用、WOW64与兼容模式 |-编程实现突破WIN7的PatchGuard |-系统服务描述结构详解 |-SSDT HOOK和UNHOOK |-SHADOW SSDT HOOK和UNHOOK |-INLINE HOOK和UNHOOK ------------------------------ 4.无HOOK监控技术 |-无HOOK监控进线程启动和退出 |-无HOOK监控模块加载 |-无HOOK监控注册操作 |-无HOOK监控文件操作 |-无HOOK监控进线程句柄操作 |-使用对象回调监视文件访问 |-无HOOK监控网络访问 |-无HOOK监视修改时间 ------------------------------ 5.零散内容 |-驱动里实现内嵌汇编 |-DKOM隐藏进程+保护进程 |-枚举和隐藏内核模块 |-强制结束进程 |-强制读写进程内存 |-枚举消息钩子 |-强制解锁文件 |-初步探索PE32+格式文件 ------------------------------ 6.用户态HOOK与UNHOOK |-RING3注射DLL到系统进程 |-RING3的INLINE HOOK和UNHOOK |-RING3的EAT HOOK和IAT HOOK ------------------------------ 7.反回调 |-枚举与删除创建进线程回调 |-枚举与删除加载映像回调 |-枚举与删除注册回调 |-枚举与对抗MiniFilter |-枚举与删除对象回调

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值