第2章策略模式
一 概念
- 策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
二 UML图
- Strategy 策略类,定义所有支持的算法的公共接口。
- Context 上下文,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用。
- 具体策略类,封装了具体的算法或行为,继承于Strategy类。
三 策略模式解析
- 策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
- 策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单元单独测试。
- 策略模式是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。
四 C++实现代码
#include "pch.h"
#include <iostream>
using namespace std;
//现金收取类的抽象方法 Strategy类
//定义所有支持的算法的公共接口
class CashSuper
{
public:
virtual double acceptCash(double money) = 0;
};
//正常收费子类
class CashNormal : public CashSuper
{
public:
double acceptCash(double money) override
{
return money; //正常收费 返回原价即可
}
};
//打折收费子类
class CashRebate : public CashSuper
{
public:
CashRebate(double moneyRebate)
{
this->_moneyRebate = moneyRebate;
}
double acceptCash(double money) override
{
return this->_moneyRebate * money;
}
private:
double _moneyRebate;
};
//返利收费子类
class CashReturn : public CashSuper
{
public:
CashReturn(double moneyCondition, double moneyReturn)
:_moneyCondition(moneyCondition), _meneyReturn(moneyReturn) {}
double acceptCash(double money) override
{
double result = money;
if (money > this->_moneyCondition)
{
result = money - static_cast<double>(money) / this->_moneyCondition * this->_meneyReturn;
}
return result;
}
private:
double _moneyCondition;
double _meneyReturn;
};
class CashContext
{
public:
//通过构造方法,传入具体的收费策略
CashContext(int type)
{
cs = nullptr;
switch (type)
{
case 1:
cs = new CashNormal();
break;
case 2:
cs = new CashReturn(300, 100);
break;
case 3:
cs = new CashRebate(0.8);
break;
default:
break;
}
}
~CashContext()
{
if (cs != nullptr)
{
delete cs;
this->cs = nullptr;
}
}
//根据收费策略的不同,获得计算结果
double GetResult(double money)
{
return this->cs->acceptCash(money);
}
private:
CashSuper* cs;
};
int main()
{
CashContext* cc = nullptr;
cc = new CashContext(1);
cout << "正常收费: " << cc->GetResult(400) << endl;
CashContext* cc2 = nullptr;
cc2 = new CashContext(2);
cout << "满300减100: " << cc2->GetResult(400) << endl;
CashContext* cc3 = nullptr;
cc3 = new CashContext(3);
cout << "打8折: " << cc3->GetResult(400) << endl;
return 0;
}