策略模式
★策略模式中体现了两个非常基本的面向对象设计的原则:
--封装变化的概念
--编程中使用接口,而不是对接口的实现
★面向接口的编程,实现类之间的弱耦合
★策略模式的定义
--定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。
--策略模式使这些算法在客户端调用它们的时候能够互不影响变化。
★策略模式的组成
--抽象策略角色:策略类,通常由一个接口或者抽象类实现
--具体角色:包装了相关的算法和行为。
--环境角色:持有一个策略类的引用,最终给客户端调用。
★策略模式的实现:
--策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。
--策略模式使得算法可以在不影响到客户端的情况下发生变化。使用策略模式可以把行为和环境分割开来。
--环境类负责维持和查询行为类,各种算法则在具体策略中提供。由于算法和环境独立开来,算法的修改都不会影响环境和客户端。
★策略模式的缺点
1.客户端必须知道所有的策略类,并自行决定使用哪一个策略类
2.造成很多的策略类。
★解决方案—采用工厂方法。
抽象策略角色
public interface AbstractStrategy { public int calculate(int a , int b); } |
具体角色
public class AddStrategy implements AbstractStrategy { public int calculate(int a, int b) { return a + b; } } public class DevideStrategy implements AbstractStrategy { public int calculate(int a, int b) { return a / b ; } } public class MutipleStrategy implements AbstractStrategy { public int calculate(int a, int b) { return a * b; } } public class SubtractStrategy implements AbstractStrategy { public int calculate(int a, int b) { return a - b; } } |
环境角色
public class Enviorment { private AbstractStrategy strategy; public Enviorment(AbstractStrategy
strategy) { this.strategy = strategy; } public AbstractStrategy
getStrategy() { return strategy; } public void setStrategy(AbstractStrategy
strategy) { this.strategy = strategy; } public int calculate(int a , int b) { return strategy.calculate(a, b); } } |
★应用举例:
有这样一个类
public class Person { private int id; private String name; private int age; } |
使用一个集合来保存它的多个对象,要求对这个集合进行排序,排序规则如下:
可以按Id,name, age进行升序或降序排列,当name 或age相同时,要求按id的升序进行排序。
★具体实现过程
Person类
public class Person { private int id; private String name; private int age; public Person(int id , String
name, int age) { this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + id; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (id != other.id) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } public String toString() { return "Person [id=" + id + ", name=" + name + ", age=" + age + "]"; } } |
抽象策略类
public interface AbstractSortStrategy { public void ascSort(); public void descSort(); } |
ID排序类
public class IdSortStrategy implements
AbstractSortStrategy { private List list; public IdSortStrategy(List list) { this.list = list; } public void ascSort() { Collections.sort(list , new IdComparator()); } public void descSort() { Comparator r = Collections.reverseOrder(new IdComparator()); Collections.sort(list, r); } } class IdComparator implements Comparator { public int compare(Object arg0, Object arg1) { Person p1 = (Person)arg0; Person p2 = (Person)arg1; return p1.getId()-p2.getId(); } } |
Name排序类
public class NameSortStrategy implements
AbstractSortStrategy { private List list; public NameSortStrategy(List list) { this.list = list; } public void ascSort() { Collections.sort(list , new
NameComparator()); } public void descSort() { Comparator r = Collections.reverseOrder(new
NameComparator()); Collections.sort(list, r); } } class NameComparator implements Comparator { public int compare(Object arg0, Object arg1) { Person p1 = (Person)arg0; Person p2 = (Person)arg1; if(p1.getName() == p2.getName()) { return p1.getId() - p2.getId(); } return
p1.getName().compareTo(p2.getName()); } } |
Age排序类
public class AgeSortStrategy implements
AbstractSortStrategy { private List list; public AgeSortStrategy(List list) { this.list = list; } public void ascSort() { Collections.sort(list , new
AgeComparator()); } public void descSort() { Comparator r = Collections.reverseOrder(new
AgeComparator()); Collections.sort(list, r); } } class AgeComparator implements Comparator { public int compare(Object arg0, Object arg1) { Person p1 = (Person)arg0; Person p2 = (Person)arg1; if(p1.getAge() == p2.getAge()) { return p1.getId() - p2.getId(); } return p1.getAge()-p2.getAge(); } } |
管理排序规则类
public class PersonSort { private AbstractSortStrategy strategy; public
PersonSort(AbstractSortStrategy strategy) { this.strategy = strategy; } public AbstractSortStrategy
getStrategy() { return strategy; } public void
setStrategy(AbstractSortStrategy strategy) { this.strategy = strategy; } public void ascSort() { strategy.ascSort(); } public void descSort() { strategy.descSort(); } } |
测试结果
public class PersonTest { public static void main(String[] args) { List list = new ArrayList(); Person p1 = new Person(8 , "Bob", 23); Person p2 = new Person(7 , "Jack", 25); Person p3 = new Person(1 , "Mike", 30); Person p4 = new Person(6 , "Judy", 21); Person p5 = new Person(4 , "Lisa", 35); Person p6 = new Person(5 , "Linda", 36); Person p7 = new Person(2 , "Joho", 22); Person p8 = new Person(3 , "Bob", 25); list.add(p1); list.add(p2); list.add(p3); list.add(p4); list.add(p5); list.add(p6); list.add(p7); list.add(p8); //排序前的状态 System.out.println("排序前的状态"); output(list); //-----------------Id排序测试--------------------------------------- System.out.println("Id排序测试"); PersonSort sort = new PersonSort(new
IdSortStrategy(list)); TestSort(list, sort); //----------------姓名排序测试---------------------------------------- System.out.println("姓名排序测试"); sort = new PersonSort(new NameSortStrategy(list)); TestSort(list, sort); //----------------年龄排序测试---------------------------------------- System.out.println("年龄排序测试"); sort = new PersonSort(new AgeSortStrategy(list)); TestSort(list, sort); } private static void TestSort(List
list,PersonSort sort) { sort.ascSort(); System.out.println("升序排列"); output(list); sort.descSort(); System.out.println("降序排列"); output(list); } private static void output(List list) { for(int i = 0; i<list.size(); i++) { Person p = (Person)list.get(i); System.out.println(p); } System.out.println("---------------"); } } |