C++策略模式

策略模式:
    它定义了算法家族,分别封装起来,让它们之间可以相到替换,此模式用算法的变化不会影响到其它的客户。
 
   
 

此模式还是其实就是我们平常写的代码,其实设计模式就是告诉你如何写代码罢了,并不是什么搬来就可以用的方案,如果是这样,为鸟不直接写在库作框架调用就得了,因为它仅仅提供一种解决方案。它只是告诉你有与它相似需求的时候,代码该怎么写。这样写出来的代码它的扩展性好,容易维护,类之间的耦合度低。

策略模式迎合了几个面向对象的设计思想:
    1、找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
    2、多用组合,少用继承。
    3、针对接口而不是实现编程。

引用《Head First 设计模式》中的例子:
    假如我们要设一个鸭子类:
那么一般的想法就是:
    
在基类中,有fly(),swim(),quack()这些函数接口,然后在子类中只要实现这些接口就行了。但是问题来了,例如我们要实现一个“旱鸭子”和“橡皮鸭”。你会发现,感觉在设计上逻辑有点不太对了,像皮鸭会叫吗?它会有quack()或者fly()函数接口吗?而旱鸭子会有swim()方法?这些肯定是不对的。
    问题在于这种设计思路不太符合:
         2、多用组合,少用继承。
    原则,都用继承就没有那么灵活了。
或者你会这么设计:
    
 这样也许是个好设计,把fly()和swim单独弄出来作一个类,然后单独继承,这样设计倒是符合:
1、找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
但是Acton类本来应该也是Duck该有的,Action应该是属于Duck类。单独分开来继承,可能实现上没有太大的影响 ,但是从逻辑上好像也不太好,好像有人非得把你“五马分尸”。
所以总结下,这么设计:
    
也就是将Action作为Duck的成员,再在它自己的方法中调用Action中的接口。
  1. voidDuck::peformfly(){
  2. this->action.fly();
  3. }

上面的框图的,代码实现。
 1     #include<iostream>
 2     #include<string>
 3     classStratery{
 4     public:
 5         Stratery(){
 6         }
 7         virtualvoidAlgorithmInterface(){
 8             std::cout<<"AlgorithmInterface"<<std::endl;
 9         }
10     };
11     classConcreteStrateryA:publicStratery{
12     public:
13         virtualvoidAlgorithmInterface(){
14             std::cout<<"ConcreteStrateryA"<<std::endl;
15         }
16     };
17     classConcreteStrateryB:publicStratery{
18     public:
19        virtualvoidAlgorithmInterface(){
20             std::cout<<"ConcreteStrateryB"<<std::endl;
21        }
22     };
23     classConcreteStrateryC:publicStratery{
24     public:
25         virtualvoidAlgorithmInterface(){
26             std::cout<<"ConcreteStrateryC"<<std::endl;
27         }
28     };
29     classContext{
30     private:
31         Stratery*stratery;
32     public:
33         Context(Stratery*_stratery):stratery(_stratery){
34         }
35        voidContextInterface(){
36            stratery->AlgorithmInterface();
37        }
38     };
39     int main(){
40         Context contextA(newConcreteStrateryA());
41         contextA.ContextInterface();
42         Context contextB(newConcreteStrateryB());
43         contextB.ContextInterface();
44         Context contextC(newConcreteStrateryB());
45         contextC.ContextInterface();
46     }

 


上面的实现,就是使用了策略模式的经典用法。
其中:
  1. ConcreteStrateryA
  1. ConcreteStrateryB
  1. ConcreteStrateryC
就是算法家族。这些算法之间是没有耦合的。这也是策略模式的要点之一。
可以说,策略模式就是用来封装算法,但是也可以扩展到所有其它与之要求相似的类。例如前面的Duck类,那么Duck类中封装的算法就是
Action了。
 
    
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 





posted @ 2017-05-31 23:19  yml435  阅读(339)  评论(0编辑  收藏  举报