策略模式
策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
适用性
许多相关的类仅仅是行为有异。策略提供了一种用多个行为中的一个行为来配置一个类的方法。
需要使用一个算法的不同变体。
算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
结构
Strategy - 定义所有支持的算法的公共接口。Context使用这个借口来调用某ConcreteStrategy定义的算法。
ConcreteStrategy - 以Strategy接口实现某具体算法。
Context - 用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
协作:
Strategy和Context相互作用以实现选定的算法。当算法被调用时,Context可以将该算法所需要的所有数据都传递给该Strategy。或者,Context可以将自身作为一个参数传递给Strategy操作。这就让Strategy在需要时可以回调Context。
Context将它的客户的请求转发给它的Strategy。客户通常创建并传递一个ConcreteStrategy对象给该Context; 这样,客户仅与Context交互。通常有一系列的ConcreteStrategy类可供客户从中选择。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include <iostream>
class Strategy { public: virtual void algorithm_interface() = 0; };
class ConcreteStrategyA : public Strategy { public: virtual void algorithm_interface() { std::cout << "ConcreteStrategyA" << std::endl; } };
class ConcreteStrategyB : public Strategy { public: virtual void algorithm_interface() { std::cout << "ConcreteStrategyB" << std::endl; } };
class Context { public: Context(Strategy* s) : m_strategy(s) {} virtual void context_interface() { if (!m_strategy) return; m_strategy->algorithm_interface(); } void set_strategy(Strategy* s) {m_strategy = s;} protected: Strategy* m_strategy; };
int main() { ConcreteStrategyA a; ConcreteStrategyB b; Context c(&a); c.context_interface(); c.set_strategy(&b); c.context_interface(); system("Pause"); }
|
相关模式
- Flyweight: Strategy对象经常是很好的轻量级对象。
[1] 设计模式:可复用面向对象软件的基础
[2] Head First设计模式