策略模式是指:对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。
策略模式:
- 创建表示各种策略的对象
- 创建一个行为随着策略对象改变而改变的 context 对象
- 策略对象改变 context 对象的执行算法。
UML图
代码示例:
策略类
// 策略接口
class StrategyInterface {
public:
virtual int doOperation(int num1, int num2) = 0;
};
// 策略A
class OperationSubstract : public StrategyInterface {
public:
virtual int doOperation(int num1, int num2) {
return num1 - num2;
}
};
// 策略B
class OperationMultiply : public StrategyInterface {
public:
virtual int doOperation(int num1, int num2) {
return num1 * num2;
}
};
Context类
// 管理所有策略
class Context {
public:
Context(StrategyInterface *strategy) : strategy_(strategy) { }
void set_strategy(StrategyInterface *strategy) {
strategy_ = strategy;
}
int doOperation(int num1, int num2) {
return strategy_->doOperation(num1, num2); // 多态
}
private:
StrategyInterface* strategy_;
};
测试
OperationSubstract operationSubstract;
OperationMultiply operationMultiply;
Context contextA(&operationSubstract);
Context contextB(&operationMultiply);
cout << "2 - 3 = " << contextA.doOperation(2, 3) << endl;
cout << "2 * 3 = " << contextB.doOperation(2, 3) << endl;
//*****************************输出*************************//
2 - 3 = -1
2 * 3 = 6
静态代理
上面是实现动态代理,C++还可以可用模板实现静态代理。
template <typename T>
class Context
{
public:
int doOperation(int num1, int num2) {
return strategy_.doOperation(num1, num2);
}
private:
T strategy_;
};
int main()
{
Context<OperationMultiply> ct;
ct.doOperation(1, 2);
}
总结
- 主要解决:
在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。 - 如何解决:
将这些算法封装成一个一个的类,任意地替换。 - 关键代码:
实现同一个接口。 - 优点:
1、算法可以自由切换。
2、避免使用多重条件判断。
3、扩展性良好。 - 缺点:
1、策略类会增多。
2、客户端必须知道所有的策略类,并自行决定使用哪一个策略类 - 使用场景:
1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
2、一个系统需要动态地在几种算法中选择一种。
3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
参考资料
http://www.runoob.com/design-pattern/strategy-pattern.html
https://zh.wikipedia.org/wiki/%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F