西宁网站开发公司,网站模板使用,腾讯云域名控制台,电子商务网站建设考试重点策略模式#xff08;Strategy#xff09;是一种行为型设计模式#xff0c;它允许你在运行时选择算法的行为。
策略模式有三个组件#xff1a;
策略接口#xff1a;定义了策略类必须实现的方法#xff0c;它通常是以接口或者抽象类的方式存在具体策略类#xff1a;实现…策略模式Strategy是一种行为型设计模式它允许你在运行时选择算法的行为。
策略模式有三个组件
策略接口定义了策略类必须实现的方法它通常是以接口或者抽象类的方式存在具体策略类实现了策略接口提供各种算法。上下文类将策略接口作为一个成员变量运行时通过设置不同的策略类切换不同的算法
举例 现在我们有一笔金额要按照不同国家的汇率进行计算我们可以这样实现
// 各国汇率
enum Rate
{CN_Rate, // 中国汇率FR_Rate, // 英国汇率US_Rate // 没过汇率
};// 运行
class CalculateRate
{
public:CalculateRate(){}~CalculateRate(){}void SetRate(Rate _rate){rate_ _rate;}double Calculate(const double _data){if (rate_ CN_Rate){// TODO 按照中国汇率进行计算std::cout 中国汇率 std::endl;}else if (rate_ FR_Rate){// TODO 按照法国汇率进行计算std::cout 法国汇率 std::endl;}else if (rate_ US_Rate){// TODO 按照美国汇率进行计算std::cout 美国汇率 std::endl;}return 0.0;}private:Rate rate_;
};我们定义了一个枚举里面是各个国家的类型当我们要按照美国的汇率进行计算时我们可以通过SetRate方法设置国家类型再调用Calculate方法进行计算在这个方法里我们会判断当前是哪个国家执行对应的算法。
其实这个例子已经实现了我们现在的需求但是项目开发过程中需求是不断的变化。比如现在我们要加一个日本的汇率我们应该在枚举里添加一个日本在Calculate方法里继续else if执行日本汇率对应的算法。
这样其实违背了项目开发原则中的开放封闭原则。
所谓开放封闭原则就是对扩展开放、对修改封闭换句话说我们应该通过添加新的代码来实现需求而不是修改原有的代码。
现在我们用策略模式来完成这个需求按照上述策略模式的三个组件来编写代码策略接口、具体的策略类、上下文类
// 定义策略接口
class Strategy
{
public:virtual ~Strategy(){}virtual double CalculateRate(const double _data) 0;
};// 根据中国汇率计算的策略类
class CNRateStrategy: public Strategy
{
public:virtual double CalculateRate(const double _data) override{// TODO 按照中国汇率进行计算std::cout 中国汇率 std::endl;return 0.0;}
};// 按照法国汇率计算的策略类
class FRRateStrategy: public Strategy
{
public:virtual double CalculateRate(const double _data) override{// TODO 按照法国汇率进行计算std::cout 法国汇率 std::endl;return 0.0;}
};// 按照美国汇率计算的策略类
class USRateStrategy: public Strategy
{
public:virtual double CalculateRate(const double _data) override{// TODO 按照美国汇率进行计算std::cout 美国汇率 std::endl;return 0.0;}
};// 上下文类
class Context
{
public:Context(){}void SetRate(std::shared_ptrStrategy _strategy){strategy_ _strategy;}void Calculate(const double _value){if(strategy_)strategy_-CalculateRate(_value);}private:std::shared_ptrStrategy strategy_;
};我们通过Context类里的SetRate方法设置具体的策略类通过Calculate方法执行算法。
void TestStrategy()
{Context context;context.SetRate(std::make_sharedCNRateStrategy());context.Calculate(10.0);context.SetRate(std::make_sharedFRRateStrategy());context.Calculate(10.0);context.SetRate(std::make_sharedUSRateStrategy());context.Calculate(10.0);
}int main()
{// 策略模式用法TestStrategy();system(pause);return 0;
}现在我们要添加一个日本的汇率我们就可以仿照美国、中国、法国的策略类的写法写一个日本的策略类在运行的时候设置日本的策略类这样它就会执行日本的算法。
我们可以发现使用策略模式就不会违背开放封闭原则因为我们是添加代码而不是修改原有代码。
可能会有人说第一种写法不是也是添加代码吗我们这里说的“添加”是在二进制的角度所谓的添加是指添加之后编译添加后的代码而不是把原有代码重新编译一遍。
总结
Strategy及其子类为组件提供了一系列可重用的算法从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换Stratergy模式提供了用条件判断语句以外的另一种选择消除条件判断语句就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式。如果Strategy对象没有实例变量那么各个上下文可以共享同一个Strategy对象从而节省对象开销