C++设计模式学习笔记三:策略模式

1、先看看策略模式的官方定义:

The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.(策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。)

策略模式类图如下:

                                                       C++设计模式学习笔记三:策略模式_第1张图片

2、《大话设计模式》实现策略模式中,使用到了反射。前面也说过,在C++中实际没有反射,需要自己实现。为实现反射,我模仿MFC中RTTI的dynamic调用,利用链表实现了个简单的反射功能。代码如下:

ReflectionFunc.h

#pragma once
#include "stdafx.h"
#include 
#include 
#include 
using namespace std;

typedef void* (*CreateFunc)();

struct ClassFactory
{
	std::string m_strName;
	CreateFunc m_pObject;

	static void* GetClassByName(std::string strName);

	static ClassFactory* pFirstClass;
	ClassFactory* m_pNextClass;
};

struct MY_CLASSINIT
{ 
	MY_CLASSINIT(ClassFactory* pNewClass); 
};

#define DECLARE_MYCLASS(class_name) \
	static void* CreateObject(class_name);\
	static ClassFactory m_CF##class_name;

#define IMPLEMENT_MYCLASS(class_name)\
	static char my##class_name[] = #class_name;\
	void* class_name::CreateObject(class_name) { return new class_name; }\
	ClassFactory class_name::m_CF##class_name = {my##class_name, (CreateFunc)class_name::CreateObject};\
	static MY_CLASSINIT _init_##class_name(&class_name::m_CF##class_name); 
	
ReflectionFunc.cpp

#pragma once
#include "StdAfx.h"
#include "ReflectionFunc.h"

ClassFactory* ClassFactory::pFirstClass = NULL;

void* ClassFactory::GetClassByName(std::string strName)
{
	void* pObject=NULL;
	ClassFactory* pClass = pFirstClass;
	for (;pClass!=NULL;pClass=pClass->m_pNextClass)
	{
		if (pClass->m_strName.compare(strName) == 0)
		{
			pObject = pClass->m_pObject();
		}
	}
	return pObject;
}

MY_CLASSINIT::MY_CLASSINIT(ClassFactory* pNewClass)
{
	pNewClass->m_pNextClass = ClassFactory::pFirstClass;
	ClassFactory::pFirstClass = pNewClass;
}

3、策略模式的其他部分代码实现如下:

CashContext.h

#pragma once
#include "StrategyPattern.h"
#include "CashSuper.h"
#include 
using namespace std;

class STRATEGYPATTERN_API CCashContext
{
public:
CCashContext(void);
~CCashContext(void);

void SetBehavior(std::string strClassName, char szParam[]);
double GetResult(double money);

private:
CCashSuper* m_pCashSuper;
};

CashContext.cpp

#pragma once
#include "StdAfx.h"
#include "CashContext.h"
#include "ReflectionFunc.h"

CCashContext::CCashContext(void)
{

}


CCashContext::~CCashContext(void)
{
	
}

void CCashContext::SetBehavior(std::string strClassName, char szParam[])
{
	CCashSuper* pCash = (CCashSuper*)ClassFactory::GetClassByName(strClassName);
	if (!pCash) return;
	pCash->SetClassParam(szParam);
	m_pCashSuper = pCash;
}

double CCashContext::GetResult(double money)
{
	return m_pCashSuper->acceptCash(money);
}

CashSuper.h

#pragma once
#include 
#include "ReflectionFunc.h"

class CCashSuper
{
public:
	CCashSuper(void);
	~CCashSuper(void);

	virtual void SetClassParam(const char* pParam)=0;
	virtual double acceptCash(double money)=0;
};


CashRebate.h

#pragma once
#include "cashsuper.h"
#include "Utility.h"

class CCashRebate :public CCashSuper
{
public:
	DECLARE_MYCLASS(CCashRebate)
	CCashRebate(void);
	~CCashRebate(void);

	virtual void SetClassParam(const char* pParam);
	virtual double acceptCash(double money);

private:
	double m_Rebate;
};


CashRebate.cpp

#pragma once
#include "StdAfx.h"
#include "CashRebate.h"

IMPLEMENT_MYCLASS(CCashRebate)

CCashRebate::CCashRebate(void)
{
	m_Rebate = 1;
}


CCashRebate::~CCashRebate(void)
{
}

double CCashRebate::acceptCash(double money)
{
	return money * m_Rebate;
}

void CCashRebate::SetClassParam(const char* pParam)
{
	std::string str(pParam);
	std::vector vecStr;
	CUtility::GetInstance().SplitString(str, vecStr);
	m_Rebate = atof(vecStr[0].c_str());
}

其他策略方法CCashReturn、CCashNormal类实现与CCashRebate类似,这里就不copy出来了。

完整的代码下载地址如下:

http://download.csdn.net/detail/cz168love/7573781

你可能感兴趣的:(设计模式)