策略模式
定义
策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
角色
环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。
具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。
使用场景
当存在以下情况时使用Strategy模式
1、多个类只区别在表现行为不同。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
2、需要使用一个算法的不同变体。
3、对客户(Duck)隐藏具体策略(算法)的实现细节,彼此完全独立。
4、一个类定义了多种行为 , 且这些行为在该类的操作中以多个条件语句的形式出现。将相关条件分支移入它们各自的Strategy类中以代替这些条件语句。
优缺点
对于Strategy模式来说,主要有如下优点:
1、 提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。
2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
对于Strategy模式来说,主要有如下缺点:
1、因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
2、客户端必须知道所有的策略类,并自行决定使用哪一个策略类:
与状态模式的比较
1、策略模式只是在对象初始化的时候更改执行模式,而状态模式是根据对象实例的周期时间而动态地改变对象实例的执行模式。
2、使用策略模式时,客户端需要知道所选的具体策略是哪一个,而使用状态模式时,客户端无须关心具体状态,环境类的状态会根据用户的操作自动转换。
1 class COperation 2 { 3 public: 4 int m_nFirst; 5 int m_nSecond; 6 7 virtual double GetResult() = 0; 8 }; 9 //加法 10 class AddOperation : public COperation 11 { 12 public: 13 AddOperation(int a,int b) 14 { 15 m_nFirst = a; 16 m_nSecond = b; 17 } 18 19 virtual double GetResult() 20 { 21 return m_nFirst + m_nSecond; 22 } 23 }; 24 //减法 25 class SubOperation : public COperation 26 { 27 public: 28 SubOperation(int a,int b) 29 { 30 m_nFirst = a; 31 m_nSecond = b; 32 } 33 34 virtual double GetResult() 35 { 36 return m_nFirst - m_nSecond; 37 } 38 }; 39 40 /*************************************************/ 41 // 1.策略模式的实现-策略模式的环境类 42 class Context 43 { 44 private: 45 COperation* op; 46 public: 47 Context(COperation* temp) 48 { 49 op = temp; 50 } 51 double GetResult() 52 { 53 return op->GetResult(); 54 } 55 } 56 /*************************************************/ 57 // 2.简单工厂模式的实现-简单工厂模式的工厂类 58 class CCalculatorFactory 59 { 60 public: 61 static COperation* Create(char cOperator ,int a ,int b); 62 }; 63 64 COperation* CCalculatorFactory::Create(char cOperator, int a, int b) 65 { 66 COperation *oper; 67 68 switch (cOperator) 69 { 70 case '+': 71 oper=new AddOperation(a, b); 72 break; 73 case '-': 74 oper=new SubOperation(a, b); 75 break; 76 default: 77 break; 78 } 79 return oper; 80 } 81 /*************************************************/ 82 // 3.工厂模式的工厂类 83 class CCalculatorFactory 84 { 85 public: 86 virtual COperation* Create(int a, int b) = 0; 87 }; 88 89 class AddFactory : public CCalculatorFactory 90 { 91 92 public: 93 COperation* Create(int a, int b) 94 { 95 return new AddOperation(a, b); 96 } 97 }; 98 99 class SubFactory : public CCalculatorFactory 100 { 101 public: 102 virtual COperation* Create(int a, int b) 103 { 104 return new SubOperation(a, b); 105 } 106 }; 107 /*************************************************/ 108 // 4.策略+工厂的实现 109 class Context 110 { 111 private: 112 COperation* op; 113 public: 114 Context(char cType, int a, int b) 115 { 116 switch(cType) 117 { 118 case '+': 119 op = new AddOperation(a, b); 120 break; 121 case '-': 122 op = new SubOperation(a, b); 123 break; 124 default: 125 break; 126 } 127 } 128 double GetResult() 129 { 130 return op->GetResult(); 131 } 132 }; 133 /*************************************************/ 134 135 // 客户端 136 int main() 137 { 138 int a,b; 139 cin>>a>>b; 140 // 简单工厂模式 141 COperation * op = CCalculatorFactory::Create('-', a, b); 142 cout<<op->GetResult()<<endl; 143 144 // 工厂方法模式 145 CCalculatorFactory* p = new AddFactory; 146 COperation* op = p->Create(a, b); 147 cout<<op->GetResult()<<endl; 148 149 // 策略模式 150 cin>>c; 151 Context *context; 152 switch(c) 153 { 154 case '+': 155 context = new Context(new AddOperation(a, b)); 156 break; 157 case '-': 158 context = new Context(new SubOperation(a, b)); 159 break; 160 default: 161 break; 162 } 163 cout<<context->GetResult()<<endl; 164 165 // 策略+工厂模式 166 Context *context = new Context('+', a, b); 167 cout<<context->GetResult()<<endl; 168 169 return 0; 170 171 }