Strategy 策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。也称为 Policy 政策。
Strategy 策略模式适用于:
1.许多相关的类仅仅是行为有异。“策略”提供了一种用于多个行为中的一个行为来配置一个类的方法。
2.需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时,可以使用策略模式。
3.算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
4.一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语种的形式出现。将相关的条件分支移入它们各自的 Strategy 类中以代替这些条件语句。
Strategy 策略模式通用结构图如下:
参与者:
Strategy:策略,定义所有支持的算法的公共接口。Context 使用这个接口来调用某 ConcreteStrategy 定义的算法。
ConcreteStrategy:具体策略,以 Strategy 接口实现某具体算法。
Context:上下文,用一个 ConcreteStrategy 对象来配置,维护一个 Strategy 对象的引用,可定义一个接口来让 Strategy 访问它的数据。
Strategy 和 Context 相互作用以实现选定的算法,当算法被调用时,Context 可以将该算法所需要的所有数据都传递给该 Strategy。或者,Context 可以将自身作为一个参数传递给 Strategy 操作,这就让 Strategy 在需要时可以回调 Context。
Context 将它的客户的请求转发给它的 Strategy。客户通常创建并传递一个 ConcreteStrategy 对象给该 Context;这样,客户仅与 Context 交互,通常有一系列的 ConcreteStrategy 类可供客户从中选择。
实现时,Context 和 Stategy 接口必须使得 ConcreteStrategy 能够有效的访问它所需要的 Context 中的任何数据,反之亦然。一种办法是让 Context 将数据放在参数中传递给 Strategy 操作,也就是说将数据发送给 Strategy。这使得 Strategy 和 Context 解耦。另一种办法是让 Context 将自身作为一个参数传递给 Strategy,该 Strategy 再显式地向该 Context 请求数据。或者 Strategy 可以存储对它的 Context 的一个引用,这样根本不再需要传递任何东西,这两种情况下,Strategy 都可以请求到它所需要的数据。
Strategy 策略模式代码示例:
1: //Stragegy.h
2: #pragma once
3:
4: class Strategy;
5:
6: //Context
7: class Context
8: {
9: public:
10: Context(Strategy *pStrategy);
11: ~Context();
12:
13: //定义一个接口,让 Strategy 访问它的数据
14: void ContextInterface();
15: private:
16: //Context 维护一个 Strategy 对象实例
17: Strategy* m_pStrategy;
18: };
19:
20: //Strategy
21: //定义所有算法支持的算法的公共接口
22: //Context 使用这个接口来调用某 ConcreteStrategy 定义的算法
23: class Strategy
24: {
25: public:
26: virtual ~Strategy(){}
27: virtual void AlgorithmInterface() = 0;
28: };
29:
30: //具体的的策略类
31: class ConcreateStrategyA : public Strategy
32: {
33: public:
34: virtual ~ConcreateStrategyA(){}
35: virtual void AlgorithmInterface();
36: };
37:
38: //具体的的策略类
39: class ConcreateStrategyB : public Strategy
40: {
41: public:
42: virtual ~ConcreateStrategyB(){}
43: virtual void AlgorithmInterface();
44: };
1: //Strategy.cpp
2: #include
3: #include "Strategy.h"
4:
5: //
6: Context::Context(Strategy *pStrategy)
7: : m_pStrategy(pStrategy){}
8:
9: Context::~Context()
10: {
11: delete m_pStrategy;
12: m_pStrategy = NULL;
13: }
14:
15: void Context::ContextInterface()
16: {
17: if (NULL != m_pStrategy)
18: {
19: m_pStrategy->AlgorithmInterface();
20: }
21: }
22:
23: /
24: void ConcreateStrategyA::AlgorithmInterface()
25: {
26: std::cout << "AlgorithmInterface Implemented by ConcreateStrategyA"
27: << std::endl;
28: }
29:
30: /
31: void ConcreateStrategyB::AlgorithmInterface()
32: {
33: std::cout << "AlgorithmInterface Implemented by ConcreateStrategyB"
34: << std::endl;
35: }
1: //test.cpp
2: #include "Strategy.h"
3: #include
4:
5: int main()
6: {
7: Context* pContext1 = new Context(new ConcreateStrategyA());
8: Context* pContext2 = new Context(new ConcreateStrategyB());
9:
10: pContext1->ContextInterface();
11: pContext2->ContextInterface();
12:
13: delete pContext1;
14: delete pContext2;
15:
16: return EXIT_SUCCESS;
17: }