策略模式(strategy)
策略模式(strategy),它们定义了算法家族,分别封装起来,让它们之间可以替代,此模式让算法的变化,不会影响到使用算法的客户。
不废话,看UML图和对应C++代码:
对应C++代码:
/**
* date:2012/02/27
* Item:Learn strategy pattern
* name:smile
**/
#include <iostream>
using namespace std;
#define NORMAL 1
#define REBATE 2
#define RETURN 3
class Abs_Arithmetic
{
public:
virtual double GetTotalPrice(int num,double price) = 0;
virtual void InitValue(double rebate = 0.0,
double conditionmoney = 0.0,double Returnmoney = 0.0) = 0;
};
class NormalArithmetic:public Abs_Arithmetic
{
public:
void InitValue(double rebate = 0.0,
double conditionmoney = 0.0,double Returnmoney = 0.0){}
double GetTotalPrice(int num,double price)
{
return double(num)*price;
}
};
class RebateArithmetic:public Abs_Arithmetic
{
public:
void InitValue(double rebate = 0.0,
double conditionmoney = 0.0,double Returnmoney = 0.0)
{
Rebate = rebate;
}
double GetTotalPrice(int num,double price)
{
return double(num)*price*Rebate;
}
private:
double Rebate;
};
class ReturnArithmetic:public Abs_Arithmetic
{
public:
void InitValue(double rebate = 0.0,
double conditionmoney = 0.0,double Returnmoney = 0.0)
{
ConditionMoney = conditionmoney;
ReturnMoney = Returnmoney;
}
double GetTotalPrice(int num,double price)
{
double totalMoney = double(num)*price;
if(totalMoney >= ConditionMoney)
totalMoney -= totalMoney/ConditionMoney*ReturnMoney;
return totalMoney;
}
private:
double ConditionMoney;
double ReturnMoney;
};
class Context
{
public:
Context():pAbs(NULL){}
double GetReturnMoney(int num,double price)
{
return pAbs->GetTotalPrice(num,price);
}
Abs_Arithmetic* CreateConcreteArithmetic(int salemode)
{
switch(salemode)
{
case NORMAL:
pAbs = new NormalArithmetic;
break;
case REBATE:
pAbs = new RebateArithmetic;
break;
case RETURN:
pAbs = new ReturnArithmetic;
break;
default:
break;
}
return pAbs;
}
~Context()
{
cout << "called destructor!" << endl;
if(NULL != pAbs)
delete pAbs;
}
private:
Abs_Arithmetic *pAbs;
};
int main()
{
int Sale_Mode(RETURN);
int TotalNum(200);
double Price(30);
double Rebate(0.75);
double ConditionMoney(100.00);
double ReturnMoney(30.00);
Context mct;
Abs_Arithmetic *p = mct.CreateConcreteArithmetic(Sale_Mode);
p->InitValue(0.0,ConditionMoney,ReturnMoney);
double AcceptMoney = mct.GetReturnMoney(TotalNum,Price);
cout << "Shoule accept: " << AcceptMoney << " $!" << endl;
return 0;
}
从抽象的算法类Abs_Arithmetic分别派生了具体类NormalArithmetic,RebateArithmetic和类ReturnArithmetic分别代表一种具体的算法
然后类Context保存来一个抽象类的指针(看,又是多态的灵活运用),另外Context类提供了一个接口来创建具体的算法对象,然后提供一个接口给客户端
这样有什么好处?这样就让算法对象的创建和用户彻底隔离了,隐藏了更多信息更容易维护。这样也容易扩展,要新算法直接派生个出来就行了,然后就可以替代原来的算法。
这些算法就是变化点,是可以替代的,封装变化点是面向对象中很很重要的思维方式。