策略模式做为一种软件设计模式,指对象有某个行为,可是在不一样的场景中,该行为有不一样的实现算法。(维基百科)java
概念中说策略模式是某个行为在不一样场景下有不一样的实现算法。咱们知道有一条设计原则是这样的:分离变化的部分和不变的部分。在这个概念中咱们能够知道。不变的地方,是这个行为,变化的,是执行这个行为所须要的算法,或者说是策略。算法
这个模式的应用场景应该是这样的。咱们须要对若干个均可以实现咱们所要的功能中选择一个最合适的。举一个简单的例子:java君、Pascal君、Scala君三我的要去餐厅吃饭。但是呢,他们仨我的的口味不同,java君想吃面向对象大餐,Pascal君想吃面向过程大餐,而Scala君想吃函数式大餐,这时候假设你是餐厅服务员,你给每一个人点餐的时候,就要这样写了spring
if(pascal君) return 面向过程大餐;else if(java君)return 面向对象大餐;else if(scala君)return 函数式大餐;
这就太糟了。由于若是又来了一个spring先生想要吃aop大餐,就要去更改源码了。这不符合咱们“对修改关闭,对扩展开放”的原则。因此这种设计是不行的。编程
咱们说要分离开变化的和不变的东西。变化的就是对不一样的人要上不一样的菜。咱们把这一点从代码中分离出来。单独封装起来。利用多态,给每一类人一个点某种菜的能力。咱们可让全部人实现一个Order接口,这个接口中定义了点菜这个方法,让每一个人都去实现这个方法,而后在点菜的时候直接去调用每一个人的order方法。这样若是在来新的人的话,咱们不用改动原有的代码,只须要让新人实现本身的order方法就能够。这样就符合设计原则了。下面是实现代码。设计模式
/* * Created by 王镜鑫 on 2016/10/7 */ interface Order//点餐接口 { public void order();//点餐方法 } class JAVA implements Order//java君实现点餐接口 { public void order() { System.out.println("I want a Object Oriented meal"); } } class Pascal implements Order//Pascal君实现点餐接口 { public void order() { System.out.println("I want a Procedure Oriented meal"); } } class Scala implements Order//Scala君实现点餐接口 { public void order() { System.out.println("I want a functional meal"); } } public class Restaurant//餐厅 { private Order order = null; public void setOrder(Order order)//设置点餐的人。 { this.order = order; } public void order()//让点餐人点餐 { order.order(); } public static void main(String[] args) { Restaurant restaurant = new Restaurant();//实例化一个餐厅 restaurant.setOrder(new JAVA());//将java君设置进去 restaurant.order();//让java君点餐 restaurant.setOrder(new Pascal());//将Pascal君设置进去 restaurant.order();//让Pascal君点餐 restaurant.setOrder(new Scala());//将Scala君设置进去 restaurant.order();//让Scala君点餐 } }
输出以下:函数
I want a Object Oriented meal I want a Procedure Oriented meal I want a functional meal
可见,java君、Pascal君、Scala君都吃到了本身想吃的大餐。而且及时再来一个汇编先生,咱们也不怕,也不用修改原来的代码。只须要在添加一个汇编先生类让其实现点餐接口就能够了。this
咱们经过一个例子。来描述了所谓的策略模式的应用场景,和如何应用策略模式解决问题,使代码更易扩展,下降耦合。下面咱们总结一下策略模式。
经过上面的例子,咱们得知,策略模式包含如下角色:spa
三者的关系以下图:scala
上下文中有一个策略属性,还有一个设置策略的方法,一个工做方法。工做方法中实现的就是策略的工做方法。 具体的策略A和具体的策略B去实现了策略接口,实现了work方法。这样在调用上下文的work方法,就是调用了实际设置的具体策略的work方法,从而实现了将执行策略与具体的策略解耦,有新的策略的时候,只须要再从新声明一个策略类就能够。
策略模式是一种很是简单的设计模式,策略模式是对不一样的算法的封装,把算法的责任和算法自己分离开来,将算法委派给不一样的对象管理,用一句话来讲,策略模式就是:实现一族算法,并将每个算法都封装起来,使其相互交换。
策略模式中,使用哪种策略是由用户来决定的,这提升了系统的灵活性,可是这在必定程度上,也增长了客户端的使用难度。由于客户端须要了解不一样的算法之间的区别,选择合适的算法。策略模式还体现了这样一个设计原则:针对接口编程,而不是针对实现编程。咱们在策略模式中,用一个接口表明行为,根据多态,上下文在工做时执行的行为,是这个接口的具体实现。思考咱们经常使用的jdk官方的排序方法。Colloctions.sort(List<T> list)和他的重载方法 sort(List<T> list, Comparator<? super T> c)他们的实现都是直接调用了List的sort方法,区别是一个传入的比较器是null,一个是传入了具体的比较器,比较器是null的那个方法,list中的元素T也是实现了Comparablel接口的。这就是一个典型的策略模式的应用。再排序的时候,因为不一样的须要排序的类的排序规则不同,也就是策略不同,因此咱们把策略封装到客户部分,也就是具体须要排序的类中,也就是让具体须要排序的类实现Comparable接口,而后在传入到排序的算法中的时候,排序的算法在比较两个元素的前后顺序的时候直接调用其compareTo方法,根据多态,他调用的实际上是具体传入的compareTo方法。也就是封装到子类中的具体的比较策略,这样就能实现了具体的排序。这是策略模式在排序中的应用。
因为知识水平有限,文章中有疏漏或者错误的地方,欢迎你们留言指正。设计