策略模式
面向对象:Object Oriented,缩写为OO
—————————————————————————————————————
总述:
OO设计原则:
1.封装变化
2.多用组合,少用继承
3.针对接口编程,不针对实现编程
OO设计模式:
1.策略模式:定义算法族,分别封装起来,以便相互替换。此模式能让算法的变化独立于使用算法的客户。
——————————————————————————————————————————
我们经常会因为设计类与类之间继承关系而苦恼,设计模式给出了较全面的解决方案。
其中很重要的一个方面就是如何面对从父类到子类的方法(行为)继承中的一些变化。
变化有两种:
①父类的部分方法在子类中不会用到的情况
②父类的方法在子类中覆写的情况。
面对第一种变化,父类的部分方法在子类中不会用到的情况下,我们引入一个设计原则。
一、封装变化
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
即面对这种变化,不要将变化的方法写入父类,另立一个新类专门去表述该方法,只让拥有该方法子类去继承,不拥有此方法的子类不继承。
其他不发生改变的方法都放入父类让每个子类去继承
eg:不是所有的人都会吹口哨,那么我们设立一个能吹口哨类,只有会吹口哨的人才去继承。
面对第二种变化,父类的方法在子类中覆写的情况,将引入下一个新的设计原则。
二、针对接口编程
针对接口编程,而不是针对实现编程。
我们希望一切能有弹性,能随时给自己以及合作的人一个清晰的通道去创建同一个行为名称下的新执行方式(即新方法)。
在代码中的体现区别就是方法的具体实现不在子类中实现,而是在众多继承于同一行为接口的类中实现,这样实现之后,即是拓展了将封装后的变化行为。
利用接口代表每个行为,比如说QuackBehavior是我们设定的接口,
所以行为的对象类不会直接负责去实现该接口,而是通过一组其他的行为类去实现,这样就不会为了实现行为而实现将行为绑的死死的。
针对接口编程真正的意思其实是针对超类型编程,即多态的思想。
给我们带来的便利就是声明类之后不用在意以后执行的真正对象!
下面这个多态例子:抽象类Animal,两个具体实现类Dog,Cat继承Animal
那么至此,我们学会了OO中优化继承的几个设计原则:
①将变化的行为从父类剥离出来,放到单独的类或接口去执行
②如果是因为行为本身有多种实现方式,那么将行为设计成接口,用多个行为类去继承。
③在②的情况下,对象实例化通过多态实现。
接下来,展示一段通过上述设计原则实现的一段代码,
要求设计鸭子类有飞,叫,游泳,展示四种行为,期中飞和叫的行为分别有两种实现方式。
实例化一只米勒鸭,要求展示其可以呱呱叫并且可以飞的能力。
首先,因为叫和飞行两个行为的实现方式可变,我们用接口先将其设置好
接下来将可变行为设置好后,我们将不变行为和已经委托好的飞行和叫两个行为的接口写入父类Duck函数中
设置对象类:米勒鸭
在测试类主函数中,展示其可以呱呱叫并且可以飞的能力。
那么这样,我们就得到了想要的结果。
接下来,我们让行为执行起来更加灵活,我们来动态设定行为。
所谓动态设定无非就是要求在测试类对象实例化过程中可以调用方法更改对象行为。
承接于上一个程序我们做一些更改即可实现动态设定行为。
在父类Duck中增添setter method
在主程序中对米勒鸭的叫的行为做出修改
行为结果出现了变化
到了这里,我们回观这样的设计模式给我们带来了什么。
减少了继承,通过接口将飞行行为和叫的行为封装了起来。
这样的模式就像是鸭子的行为不是从父类继承来的,而是与挑选的被封装的关系类中的行为组合来的
这里引入第三个设计原则。
三、多用组合,少用继承
如你所见,使用组合建立系统具有很大的弹性,不仅可以将算法族封装成类,更可以在运行时动态地改变行为,只要组合的行为对象符合正确的接口标准即可。
—————————————————————————————————
到这里我们完成了策略模式的学习,想必这时你回过来看策略模式的定义,会有一个更深刻的理解
策略模式:定义算法族,分别封装起来,以便相互替换。此模式能让算法的变化独立于使用算法的客户。
—————————————————————————————————