概述
我们开发过程中会遇到实现一个功能会有多种解决方法或者说多种策略,我们可以根据当时的生产环境,选择适合的解决办法。如果单纯的按照基本开发去实现,只考虑当前策略,让类与类之间实现强依赖关系,那么后期,当我们需要更换策略时,整个解决流程代码都要重新整改,费时费力。策略模式不仅解决了这个问题,而且对于其他不同需求者都可以根据自己的策略去扩展。
例子1:对一个对象某一属性进行排序,首先对象有不同种类,同一对象又有不同数据类型,通过策略模式封装一个既可以对不同对象,又可以根据不同数据类型去排序的排序器。
其实这一点Java jdk已经为我们提供了这样的排序器接口。不过这里为了更直观说清楚,自己手写一个(把java.util.Comparator抄一遍)。
首先写一个比较器接口
package com.zl.strategy; public interface Comparator <T>{ int compareTo(T o1, T o2); }
然后来两个实体类
package com.zl.strategy; public class Dog{ Integer age; public Dog(Integer age) { this.age = age; } @Override public String toString() { return "Dog{" + "age=" + age + '}'; } }
package com.zl.strategy; public class Pig{ Integer weight; Integer height; public Pig() { } public Pig(Integer weight, Integer height) { this.weight = weight; this.height = height; } @Override public String toString() { return "Pig{" + "weight=" + weight + ", height=" + height + '}'; } }
如果想要对Dog类进行排序,直接实现比较器接口
package com.zl.strategy; public class DogComparator implements Comparator<Dog> { @Override public int compareTo(Dog o1, Dog o2) { if(o1.age>o2.age)return 1; else if(o1.age<o2.age)return -1; else return 0; } }
如果想要对Pig类不同属性进行排序,直接按照属性实现比较器接口
package com.zl.strategy; public class PigWeightComparator implements Comparator<Pig> { @Override public int compareTo(Pig o1, Pig o2) { if(o1.weight>o2.weight)return 1; else if(o1.weight<o2.weight)return -1; else return 0; } }
package com.zl.strategy; public class PigHeightComparator implements Comparator<Pig> { @Override public int compareTo(Pig o1, Pig o2) { if(o1.height>o2.height)return 1; else if(o1.height<o2.height)return -1; else return 0; } }
走到这一步,算是大功告成了,下面给出测试类,不过我把冒泡排序封装了一个类(Sorter)
package com.zl.strategy; public class Sorter<T> { public void sort(T[] ts, Comparator<T> comparator){ for(int i=0; i<ts.length; i++){ for(int j=0; j<ts.length-1-i; j++){ if(comparator.compareTo(ts[j],ts[j + 1]) > 0){ swap(ts,j,j+1); } } } } public void swap(T[] a, int i, int j){ T t=a[i]; a[i]=a[j]; a[j]=t; } }
package com.zl.strategy; import java.util.Arrays; public class Test { public static void main(String[] args) { /** * 在排序中,我们只需要调用Sorter中sort方法传入对象数组和想要的比较器实现类即可。 * 实际开发中会比排序复杂,这样优势更加明显,更改策略只需更换相应的策略实现类即可,扩展性强 */ //Dog[] dogs = {new Dog(3),new Dog(5), new Dog(1), new Dog(2)}; Pig[] pigs = {new Pig(3,3), new Pig(5,5), new Pig(1,1),new Pig(4,4)}; Sorter<Pig> sorter = new Sorter<>(); sorter.sort(pigs,new PigWeightComparator());//根据Pig类对象数组weight属性排序 System.out.println(Arrays.toString(pigs)); } }
例子2:不同的人要从北京到上海,交通出行可以选择不同的出行方式,如下图
例子3:射击游戏,小时候玩过游戏300光碟里的坦克吧,坦克吃了不同特效加成,打出的子弹就会发生改变,策略切换子弹即可。
最后放一张简单结构图