Java 设计模式之策略模式

来源:互联网 发布:蒙特卡洛算法量化 编辑:程序博客网 时间:2024/06/14 06:49

刚好工作上有个空档期,于是就复习了下Java模式,感谢博主分享的文章

1:定义:

在《head first Design Pattern》中的定义是:策略模式定义了算法族,分别分装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。

2:设计原则

1)   找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
2)   针对接口编程,而不是针对实现编程。
3)   多用组合,少用继承。
3策略模式的编写步骤

1)    对策略对象定义一个公共接口。

2)    编写策略类,该类实现了上面的公共接口。

3)    在使用策略对象的类中保存一个对策略对象的引用。

4)    在使用策略对象的类中,实现对策略对象的setget方法(注入)或者使用构造方法完成赋值。

4,实际例子:
    head first <span lang="EN-US" style="" font-size:10.5pt;"="">Design Pattern》的例子(简化后):模拟一个鸭子游戏,游戏中有三种鸭子(绿头鸭MallardDuck, 红头鸭RedheadDuck
,橡皮鸭RubberDuck,诱饵鸭DecoyDuck),鸭子们都会游泳,外表各不相同,同类型鸭子叫声相同,绿头鸭和红头鸭会飞会叫,橡皮鸭不会飞但会叫,诱饵鸭不会飞不会叫,请设计这个游戏。
1,我们可能这么设计:
该设计的缺陷是:
绿头鸭和红头鸭叫声相同,但是quack()却无法复用,如果该行为要修改,那么修改该行为非常麻烦,你必须得往下追踪并在每一个定义此行为的类中修改它,这将是可怕的。
解决方法:分开变化的与不会变化的部分;体现(设计原则1
Duck类内的fly()quack()会随着鸭子的不同而改变,将这两个行为从Duck类中分开,形成算法族

整体类结构如下所示:

详细代码:
飞行的接口:
[java] view plain copy
  1. interface FlyBehavior{  
  2.     public void fly();  
  3. }  
两个飞行类的实现:
[java] view plain copy
  1. class FlyWithwings implements FlyBehavior{  
  2.     public void fly(){  
  3.         System.out.println("can fly");  
  4.     }  
  5. }  
  6. class FlyNoWay implements FlyBehavior{  
  7.     public void fly(){  
  8.         System.out.println("can not fly");  
  9.     }  
  10. }  
叫声的接口:
[java] view plain copy
  1. interface QuackBehavior{  
  2.     public void quack();  
  3. }  
三个叫声行为的实现:
[java] view plain copy
  1. class Quack implements QuackBehavior{  
  2.     public void quack(){  
  3.         System.out.println("guagua");  
  4.     }  
  5. }  
  6. class Squeak implements QuackBehavior{  
  7.     public void quack(){  
  8.         System.out.println("zhizhi");  
  9.     }  
  10. }  
  11. class MuteQuack implements QuackBehavior{  
  12.     public void quack(){  
  13.         System.out.println("can not fly");  
  14.     }  
  15. }  
鸭子的基类:
[java] view plain copy
  1. abstract class Duck {  
  2.     FlyBehavior flyBehavior;  
  3.     QuackBehavior quackBehavior;  
  4.     public abstract void display();  
  5.     public void performFly(){  
  6.         flyBehavior.fly();  
  7.     }  
  8.     public void performQuack(){  
  9.         quackBehavior.quack();  
  10.     }  
  11.     public void swim(){  
  12.         System.out.println("All ducks can swim");  
  13.     }  
  14. }  
java Comparator使用的就是该设计模式,就是不改变对象本身,而是用一个策略对象改变它的行为;以下模拟下它的实现过程。
题目:人有年龄和身高两种属性,现在要对不同的人排序,可以按年龄也可以按身高。
人物类定义:
[java] view plain copy
  1. class perSon {  
  2.     int Age;  
  3.     int weigth;  
  4.   
  5.     perSon(int Age, int weigth) {  
  6.         this.Age = Age;  
  7.         this.weigth = weigth;  
  8.     }  
  9.     public void printinfo(){  
  10.         System.out.println("age:"+Age+"  weight:"+ weigth);  
  11.     }  
  12. }  
MyComparator接口:
[java] view plain copy
  1. interface MyComparator<T> {  
  2.     public int compare(T o1, T o2);  
  3. }  
接下来是两种比较策略,继承了接口MyComparator
[java] view plain copy
  1. class perSonSortWithweigth implements MyComparator<perSon> {  
  2.   
  3.     @Override  
  4.     public int compare(perSon o1, perSon o2) {  
  5.         // TODO Auto-generated method stub  
  6.         // TODO Auto-generated method stub  
  7.         if (o1.weigth > o2.weigth) {  
  8.             return 1;  
  9.         } else if (o1.weigth == o2.weigth) {  
  10.             return 0;  
  11.         } else {  
  12.             return -1;  
  13.         }  
  14.   
  15.     }  
  16. }  
  17.   
  18. class perSonSortWithAge implements MyComparator<perSon> {  
  19.   
  20.     @Override  
  21.     public int compare(perSon o1, perSon o2) {  
  22.         // TODO Auto-generated method stub  
  23.         if (o1.Age > o2.Age) {  
  24.             return 1;  
  25.         } else if (o1.Age == o2.Age) {  
  26.             return 0;  
  27.         } else {  
  28.             return -1;  
  29.         }  
  30.   
  31.     }  
  32. }  
接下来模拟arrays类(api中的arrays要复杂的多);
[java] view plain copy
  1. class myArrays {  
  2.     public static <T> void sort(T[] arr, MyComparator<? super T> c) {  
  3.         T temp;  
  4.         // 简单的冒泡排序  
  5.         // 比较相邻的元素。如果第一个比第二个大,就交换他们两个。  
  6.         // 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。最后的元素应该会是最大的数。  
  7.         // 针对所有的元素重复以上的步骤,除了最后一个。  
  8.         for (int i = 0; i < arr.length - 1; i++) {  
  9.             for (int j = 0; j < arr.length - i - 1; j++) {  
  10.                 if (c.compare(arr[j + 1], arr[j]) >= 0) {  
  11.                     temp = arr[j];  
  12.                     arr[j] = arr[j + 1];  
  13.                     arr[j + 1] = temp;  
  14.                 }  
  15.             }  
  16.         }  
  17.     }  
  18. }  
测试如下:
[java] view plain copy
  1. public class test {  
  2.     public static void main(String[] args) {  
  3.         perSon[] persons=new perSon[]{new perSon(1,2),new perSon(2,3),new perSon(3,0)};   
  4.         myArrays.sort(persons,new perSonSortWithAge());  
  5.         for(int i=0;i<persons.length;i++){  
  6.             persons[i].printinfo();  
  7.         }  
  8.         myArrays.sort(persons, new perSonSortWithweigth());  
  9.         for(int i=0;i<persons.length;i++){  
  10.             persons[i].printinfo();  
  11.         }  
  12.           
  13.     }  
  14. }  
0 0