定义一系列算法,把它们一个个封装起来,并且使它们可互相替换(变化)。该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)。
在策略模式中,一个类的行为或其算法可以在运行时更改。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象的改变而改变的context对象,策略对象改变context对象的执行算法。
1. 介绍
意图:定义一系类的算法,把他们一个个封装起来,并且使他们可以相互替换。
主要解决:在有多种算法类似的情况下面,使用if。。。else所带来的复杂和难以维护。
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决:将这些算法封装成一个一个的类,任意的替换。
关键代码:实现同一个接口。
应用实例:1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。
优点:1.算法可以自由切换。2。避免使用多重条件判断。3.扩展性良好
缺点:1.策略类会增多。2、所有策略类都需要对外暴露
使用场景:1、如果一个系统里面有许多类,他们之间的区别仅在于他们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。2、一个系统需要动态的额再几种算法中选择一种。3、如果一个对象有很多行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择选择语句来实现。
注意事项:如果一个系统的策略多余四个,就需要考虑使用混合模式,解决决策类膨胀的问题。
2. 实现
我们将创建一个定义活动的 Strategy 接口和实现了 Strategy 接口的实体策略类。Context 是一个使用了某种策略的类。
StrategyPatternDemo,我们的演示类使用 Context 和策略对象来演示 Context 在它所配置或使用的策略改变时的行为变化。
2.1 C++实现
代码段在程序中实现代码段分段加载,进而降低CPU对代码的负担,提高性能。
Game.h
#include <stdio.h>
class CTaxStrategy {
public:
virtual int CalculateTax(const int& val1, const int& val2) = 0;
~CTaxStrategy() { };
};
class CCnTaxStrategy : public CTaxStrategy {
int CalculateTax(const int& val1, const int& val2) {
return val1 + val2;
}
};
class CUsTaxStrategy : public CTaxStrategy{
int CalculateTax(const int& val1, const int& val2) {
return val1 - val2;
}
};
class CDeTaxStrategy :public CTaxStrategy{
int CalculateTax(const int& val1, const int& val2) {
return val1*val2;
}
};
class CSalesOder {
private:
CTaxStrategy* taxStrategy;
public:
CSalesOder(CTaxStrategy* strategy)
{
this->taxStrategy = strategy;
}
int calculateTax(const int& val1, const int& val2)
{
return taxStrategy->CalculateTax(val1, val2);
}
};
Main.c
#include<stdio.h>
#include "game.h"
int main(int argc, char** argv)
{
CSalesOder* salesOder = new CSalesOder(new CCnTaxStrategy);
printf("CCnTaxStrategy input pavameter 3, 2, return %d\n", salesOder->calculateTax(3, 2));
salesOder = new CSalesOder(new CUsTaxStrategy);
printf("CUsTaxStrategy input pavameter 3, 2, return %d\n", salesOder->calculateTax(3, 2));
salesOder = new CSalesOder(new CDeTaxStrategy);
printf("CedTaxStrategy input pavameter 3, 2, return %d\n", salesOder->calculateTax(3, 2));
while (1);
return 0;
}
3. 小结
Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换。
Strategy模式提供了用条件判断语句以外的另一种选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式。
如果Strategy对象没有实例变量,那么各个上下文可以共享同一个Strategy对象,从而节省对象开销。