策略模式:
它定义了算法家族,分别封装起来,让它们之间可以相到替换,此模式用算法的变化不会影响到其它的客户。
此模式还是其实就是我们平常写的代码,其实设计模式就是告诉你如何写代码罢了,并不是什么搬来就可以用的方案,如果是这样,为鸟不直接写在库作框架调用就得了,因为它仅仅提供一种解决方案。它只是告诉你有与它相似需求的时候,代码该怎么写。这样写出来的代码它的扩展性好,容易维护,类之间的耦合度低。
策略模式迎合了几个面向对象的设计思想:
1、找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
2、多用组合,少用继承。
3、针对接口而不是实现编程。
引用《Head First 设计模式》中的例子:
假如我们要设一个鸭子类:
那么一般的想法就是:
在基类中,有fly(),swim(),quack()这些函数接口,然后在子类中只要实现这些接口就行了。但是问题来了,例如我们要实现一个“旱鸭子”和“橡皮鸭”。你会发现,感觉在设计上逻辑有点不太对了,像皮鸭会叫吗?它会有quack()或者fly()函数接口吗?而旱鸭子会有swim()方法?这些肯定是不对的。
问题在于这种设计思路不太符合:
2、多用组合,少用继承。
原则,都用继承就没有那么灵活了。
或者你会这么设计:
这样也许是个好设计,把fly()和swim单独弄出来作一个类,然后单独继承,这样设计倒是符合:
1、找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
但是Acton类本来应该也是Duck该有的,Action应该是属于Duck类。单独分开来继承,可能实现上没有太大的影响 ,但是从逻辑上好像也不太好,好像有人非得把你“五马分尸”。
所以总结下,这么设计:
也就是将Action作为Duck的成员,再在它自己的方法中调用Action中的接口。
voidDuck::peformfly(){this->action.fly();}
上面的框图的,代码实现。
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 }
上面的实现,就是使用了策略模式的经典用法。
其中:
ConcreteStrateryA
ConcreteStrateryB
ConcreteStrateryC
就是算法家族。这些算法之间是没有耦合的。这也是策略模式的要点之一。
可以说,策略模式就是用来封装算法,但是也可以扩展到所有其它与之要求相似的类。例如前面的Duck类,那么Duck类中封装的算法就是
Action了。
null
转载于:https://www.cnblogs.com/yml435/p/6926373.html
相关资源:数据结构—成绩单生成器