策略模式:封装了一系列算法,使得它们可以相互替换
效果:算法可以独立变化
UML图:
策略模式涉及到三个角色:
- Strategy(策略):定义所有支持的算法的公共接口
- ConcreteStrategy(具体策略):实现具体算法
- Context(上下文):
- 用一个ConcreteStrategy对象来配置
- 维护一个对Strategy对象的引用
- 可定义一个接口来让Strategy访问它的数据
示例代码:
public interface TravelStrategy {
void travel();
}
public class TrainTravelStrategy implements TravelStrategy {
public void travel() {
System.out.println("火车旅行");
}
}
public class AirTravelStrategy implements TravelStrategy {
public void travel() {
System.out.println("飞机旅行");
}
}
public class CarTravelStrategy implements TravelStrategy {
public void travel() {
System.out.println("汽车旅行");
}
}
public class Traveler {
// 持有一个具体策略的对象
private TravelStrategy travelStrategy;
public void setTravelStrategy(TravelStrategy travelStrategy) {
this.travelStrategy = travelStrategy;
}
public void trave() {
this.travelStrategy.travel();
}
}
public class TravelStrategyTest {
public static void main(String[] args) {
Traveler traveler = new Traveler();
// 选择并创建需要使用的策略对象
TravelStrategy travelStrategy = new TrainTravelStrategy();
traveler.setTravelStrategy(travelStrategy);
traveler.trave();
travelStrategy = new AirTravelStrategy();
traveler.setTravelStrategy(travelStrategy);
traveler.trave();
travelStrategy = new CarTravelStrategy();
traveler.setTravelStrategy(travelStrategy);
traveler.trave();
}
}
小结:
- 使得算法可以独立变化
- 使用组合取代继承,封装了可变性,保证了“开-闭”
策略模式的精髓在于它定义的那句话:“封装了一系列算法,使得它们可以相互替换”。
策略模式的实现与工厂模式有点类似,但策略模式是将不同的算法封装成一个对象,这些不同的算法从一个抽象类或者一个接口中派生出来,客户端持有一个抽象的策略的引用,这样客户端就能动态的切换不同的策略。 而工厂模式又分为简单工厂和抽象工厂和工厂模式 ,这些工厂是为了创建对象而出现的,工厂模式创建不同的单个对象,而抽象工厂是为了创建不同的一些列的对象或者操作。
工厂模式的地址:http://blog.csdn.net/lili429/article/details/51234720
策略模式在Java中处处可以体现,TreeSet和TreeMap中均存在这样的构造方法:
TreeSet(Comparator<? super E> comparator)
TreeMap(Comparator<? super K> comparator)
,对它的描述为:构造一个空的TreeSet或TreeMap,它根据 指定比较器 进行排序。这里的指定比较器就是我们根据需要自己写的“算法”,这就是策略模式最基本的使用方式。
下面写一个Collections.sort(List list, Comparator < ? super T > c)的策略模式应用代码:
public class Person {
public int id;
public String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return "id=" + id + "== name===" + name;
}
}
//java 源码中的接口
public interface Comparator<T> {}
public class SortById implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.id - p2.id;
}
}
public class SortByName implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
}
public class PersonStrategy {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person(3, "aaa"));
list.add(new Person(1, "ccc"));
list.add(new Person(2, "ddd"));
list.add(new Person(4, "bbb"));
Collections.sort(list, new SortById());
System.out.println(list.toString());
Collections.sort(list, new SortByName());
System.out.println(list.toString());
}
}
这里只是说comparator接口的应用也是一种策略模式,具体的应用可以参考http://blog.csdn.net/lili429/article/details/51104485
参考资料设计模式PPT