本文通过一个简单的商场收费系统来理解面向对象的特性(可维护型,可扩展性,可复用性及高灵活性),将父类cashSuper的实收现金的函数定义为虚函数以便其子类cashNormal、cashRebate、cashReduce能实现自身不同的实收现金函数(多态的体现),通过与cashSuper相依赖的cashFactory类的构造函数选择不同的模式使其内部的私有成员指针指向不同的子类然后调用自身的cashAccept函数得到不同子类实现现金算法的结果(封装性)。
策略模式的结构图如下:
“策略模式的strategy类层次为context定义了一系列的可供重用的算法或行为。集成有助于析取出这些算法中的公共功能”。
“策略模式的另一个优点是简化了测试单元,因为每个算法都有自己的类,,可以通过自己的接口进行单独的测试,不会因为一个算法的改动影响另一个算法,降低了算法间的耦合性”
“策略模式使用来封装算法的,但在实践中,我们发现它几乎可以用来封装任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的规则业务,就可以考虑使用策略模式”
--《大话设计模式》
文中提到了对于switch模式的改动可以使用反射技术,感兴趣的可以自行搜索。
#include<iostream>
using namespace std;
//现金工厂类,现金收费类及其子类
class cashSuper
{
public:
virtual double cashAccept(double money);
protected:
double acceptCash = 0;
};
class cashFactory
{
public:
cashSuper* creatCashAccept(int method);
};
class cashNormal :public cashSuper {
public:
virtual double cashAccept(double money);
};
class cashRebate :public cashSuper {
public:
cashRebate(double rate);
virtual double cashAccept(double money);
private:
double m_dRate;
};
class cashReturn :public cashSuper {
public:
cashReturn(double conditionMoney, double returnMoney);
virtual double cashAccept(double money);
private:
double m_dConditionMoney;
double m_dReturnMoney;
};
//客户端程序
int main()
{
int cashMode = 0;
double moneyWithoutDebate = 0;
cout << "请输入收费模式:(1为正常收费,2为打折收费,3为满减收费)" << endl;
cin >> cashMode;
cashFactory p_cash;
cashSuper* p_cashSuper = p_cash.creatCashAccept(cashMode);
cout << "请输入未优惠前价格: " << endl;
cin >> moneyWithoutDebate;
cout << "应收现金: " << endl;
cout << p_cashSuper->cashAccept(moneyWithoutDebate) << endl;
system("pause");
return 0;
}
//类成员函数实现部分
double cashSuper::cashAccept(double money)
{
acceptCash = money;
return acceptCash;
}
cashRebate::cashRebate(double rate)
{
m_dRate = rate;
}
double cashRebate::cashAccept(double money)
{
acceptCash = money * m_dRate;
return acceptCash;
}
double cashNormal::cashAccept(double money)
{
acceptCash = money;
return acceptCash;
}
cashReturn::cashReturn(double conditionMoney, double returnMoney)
{
m_dConditionMoney = conditionMoney;
m_dReturnMoney = returnMoney;
}
double cashReturn::cashAccept(double money)
{
if (money < m_dConditionMoney)
acceptCash = money;
else
acceptCash = money - m_dReturnMoney;
return acceptCash;
}
cashSuper* cashFactory::creatCashAccept(int method)
{
cashSuper* p_cashSuper = NULL;
switch (method)
{
case (1):
p_cashSuper = new cashNormal;
break;
case (2):
p_cashSuper = new cashRebate(0.8);
break;
case (3):
p_cashSuper = new cashReturn(300, 100);
break;
}
return p_cashSuper;
}
经过改动后使用策略模式将客户端仅生成一个cashFactory的对象,在改动中通过构造函数使指针指向不同的收费子类调用其收费算法的到实际的收费,具体改动如下:
class cashFactory
{
public:
cashFactory(int moneyMethod);
double cashAccept(double money);
private:
double resultMoney;
cashSuper* p_cashSuper;
};
cashFactory::cashFactory(int moneyMethod)
{
switch (moneyMethod)
{
case(1):
p_cashSuper = new cashNormal;
break;
case(2):
p_cashSuper = new cashRebate(0.8);
break;
case(3):
p_cashSuper = new cashReturn(300, 100);
break;
}
}
double cashFactory::cashAccept(double money)
{
resultMoney = p_cashSuper->cashAccept(money);
return resultMoney;
}