Java 设计模式---策略模式
来源:互联网 发布:vb 资源文件 编辑:程序博客网 时间:2024/06/04 19:30
策略模式是一个很简单的模式,也是一个很常用的模式,可谓短小精悍,类库有很多使用策略模式的例子,所以本文以模拟类库为例子,学习策略模式,也熟悉了java类库设计中的精华,加深了我们的OO思想。
1 概念
策略模式(Strategy):它定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法的变化不会影响到使用算法的客户。(原文:The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.)
2 模拟java类库中Comparable和Comparator接口
本文实现一个简单的排序算法,通过一步步设计,设计Comparable和Comparator接口,理解了策略模式和java类库设计这2个接口的原因和不同用途。
3 最简单的排序例子
public class Test { public static void main(String[] args) { int[] nums = { 3, 4, 1, 5, 2 }; DataSortor.sort(nums); DataSortor.p(nums); }}class DataSortor { public static void sort(int[] nums) { for (int i = 0; i < nums.length; i += 1) { for (int j = i + 1; j < nums.length; j += 1) { if (nums[i] > nums[j]) { nums[i] = nums[i] + nums[j]; nums[j] = nums[i] - nums[j]; nums[i] = nums[i] - nums[j]; } } } } public static void p(int[] nums) { for (int i : nums) { System.out.print(i + " "); } System.out.println(); }}一个最简单使用冒泡的排序一个int数组,优点简单明了,缺点扩展性和代码重用性不强(不考虑算法本身,比如什么样的数据用不用的排序算法),而且支持的类型单一!
4 支持多重类型的排序算法
public class Test { public static void main(String[] args) { int[] nums = { 3, 4, 1, 5, 2 }; DataSortor.sort(nums); DataSortor.p(nums); double[] doubles = { 1.2, 0.3, 2.5, 8.9, 0}; DataSortor.sort(doubles); DataSortor.p(doubles); Dog[] dogs = {new Dog(3,3), new Dog(1,1), new Dog(5,5)}; DataSortor.sort(dogs); DataSortor.p(dogs); }}class DataSortor { public static void sort(int[] nums) { for (int i = 0; i < nums.length; i += 1) { for (int j = i + 1; j < nums.length; j += 1) { if (nums[i] > nums[j]) { nums[i] = nums[i] + nums[j]; nums[j] = nums[i] - nums[j]; nums[i] = nums[i] - nums[j]; } } } } public static void p(Dog[] dogs) { for(int i=0; i<dogs.length; i+=1) { System.out.print(dogs[i] + " "); } System.out.println(); } public static void sort(Dog[] dogs) { for (int i = 0; i < dogs.length; i += 1) { for (int j = i + 1; j < dogs.length; j += 1) { if (dogs[i].getHeight()>dogs[j].getHeight()) { Dog temp = dogs[i]; dogs[i] = dogs[j]; dogs[j] = temp; } } } } public static void p(double[] doubles) { for (double i : doubles) { System.out.print(i + " "); } System.out.println(); } public static void sort(double[] doubles) { for (int i = 0; i < doubles.length; i += 1) { for (int j = i + 1; j < doubles.length; j += 1) { if (doubles[i] > doubles[j]) { doubles[i] = doubles[i] + doubles[j]; doubles[j] = doubles[i] - doubles[j]; doubles[i] = doubles[i] - doubles[j]; } } } } public static void sort1(int[] nums) { for (int i = nums.length - 1; i >= 0; i -= 1) { for (int j = 0; j < i; j += 1) { if (nums[j] > nums[j+1]) { nums[j+1] = nums[j+1] + nums[j]; nums[j] = nums[j+1] - nums[j]; nums[j+1] = nums[j+1] - nums[j]; } } } } public static void p(int[] nums) { for (int i : nums) { System.out.print(i + " "); } System.out.println(); }}class Dog { private int height; private int weight; public Dog(int height, int weight) { super(); this.height = height; this.weight = weight; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } @Override public String toString() { return "Dog(" + height + "," + weight +")"; } }输出结果:
1 2 3 4 50.0 0.30000000000000004 1.2000000000000002 2.5 8.9Dog(1,1) Dog(3,3) Dog(5,5)添加了更多基本类型的排序和基本类的比较,但也扩展性和重用性差还是很差。
如果我们继续添加新的类,我们必须重新写比较方法,重新改我们的排序代码,排序算法不能得到重用!所以我们可以添加比较接口!
5 引入Comparable接口
public class Test { public static void main(String[] args) { Dog[] dogs = { new Dog(3, 3), new Dog(1, 1), new Dog(5, 5) }; DataSortor.sort(dogs); DataSortor.p(dogs); }}class DataSortor { public static void p(Object[] objs) { for (int i = 0; i < objs.length; i += 1) { System.out.print(objs[i] + " "); } System.out.println(); } public static void sort(Comparable[] objs) { for (int i = 0; i < objs.length; i += 1) { for (int j = i + 1; j < objs.length; j += 1) { if (objs[i].compareTo(objs[j])>0) { Comparable temp = objs[i]; objs[i] = objs[j]; objs[j] = temp; } } } }}interface Comparable { int compareTo(Object obj);}class Dog implements Comparable { private int height; private int weight; public Dog(int height, int weight) { super(); this.height = height; this.weight = weight; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } @Override public String toString() { return "Dog(" + height + "," + weight + ")"; } @Override public int compareTo(Object obj) { if (obj instanceof Dog) { Dog d = (Dog) obj; if (height > d.getHeight()) return 1; else return -1; } return 0; }}实现了Comparable接口的类,都可以使用排序算法,而不需要更改算法代码!提高的可用性,据有很大的扩展性。
但实现Comparable接口实现比较方法不能解决使用其他比较策略比较大小,比如上面使用cat的height作为比较依据,可能以后使用cat的weight作为比较依据。所以我们提出了策略模式,引入了Comparator接口,可以让cat选择比较策略,来实现不同的比较方法。
6 引入Comparator接口
public class Test { public static void main(String[] args) { Dog[] dogs = { new Dog(3, 3), new Dog(1, 1), new Dog(5, 5) }; DataSortor.sort(dogs); DataSortor.p(dogs); }}class DataSortor { public static void p(Object[] objs) { for (int i = 0; i < objs.length; i += 1) { System.out.print(objs[i] + " "); } System.out.println(); } public static void sort(Comparable[] objs) { for (int i = 0; i < objs.length; i += 1) { for (int j = i + 1; j < objs.length; j += 1) { if (objs[i].compareTo(objs[j]) > 0) { Comparable temp = objs[i]; objs[i] = objs[j]; objs[j] = temp; } } } }}interface Comparable { int compareTo(Object obj);}interface Comparator { int compare(Object o1, Object o2);}class DogHeightComparator implements Comparator { @Override public int compare(Object o1, Object o2) { if (!(o1 instanceof Dog)) return 0; if (!(o2 instanceof Dog)) return 0; Dog dog1 = (Dog) o1; Dog dog2 = (Dog) o2; if (dog1.getHeight() > dog2.getHeight()) return 1; else if (dog1.getHeight() < dog2.getHeight()) return -1; return 0; } }class Dog implements Comparable { private int height; private int weight; private Comparator comparator = new DogHeightComparator(); @Override public String toString() { return "Dog(" + height + "," + weight + ")"; } @Override public int compareTo(Object obj) { return comparator.compare(this, obj); } public Dog(int height, int weight) { super(); this.height = height; this.weight = weight; } public Comparator getComparator() { return comparator; } public void setComparator(Comparator comparator) { this.comparator = comparator; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; }}
这样可以设计不同的Comparator来实现不同的比较方式,大大的提高了程序的扩展性,但值得说的类也要实现Comparable接口,只是在Comparable接口的实现方法中使用我们自己设置的排序策略,当然我们可以指定默认的排序算法,如上,这样如果有特殊需求时,在设置相应的排序算法,极大的提高了系统的灵活性。
现在,应该对策略模式有点较深的认识了吧,知道了为什么java类库中为什么有了Comparable还有Comparator接口了吧。
7 策略模式优缺点
优点:
1、 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
缺点:
1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
2、 在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。(这本身没有解除客户端需要选择判断的压力,而策略模式与简单工厂模式结合后,选择具体实现的职责也可以由Context来承担,这就最大化的减轻了客户端的压力。)
- Java设计模式 -- 策略模式
- java设计模式-----策略模式
- java 设计模式-策略模式
- java设计模式--策略模式
- java设计模式-策略模式
- java设计模式-策略模式
- java设计模式--策略模式
- java设计模式---策略模式
- java设计模式---策略模式
- java设计模式---策略模式
- 【Java设计模式】策略模式
- java设计模式--策略模式
- Java设计模式----策略模式
- Java设计模式------------策略模式
- Java设计模式 - 策略模式
- java设计模式---策略模式
- java设计模式-策略模式
- java设计模式----策略模式
- Struts2返回JSON对象的方法总结
- 2016.1.4~2016.1.7真题回顾!-- HTML5学堂
- Menu键_subMenu设置
- php一些强有力的函数,
- Oracle undo表空间爆满的解决
- Java 设计模式---策略模式
- php 采集新闻网站示例
- ejb的各个模块在eclipse中导入模块的jar包
- Android加载图片资源的几种方式
- Unity 3D 点乘和叉乘
- uvala 4123 WF2008 Glenbow Museum
- 看到一篇写HandlerThread的干货
- springmvc下Jersey 搭建RESTful服务
- ubuntu下调节屏幕亮度