策略模式,顾名思义,是使用不同的策略解决问题的模式,孙悟空有七十二变,孙子兵法有三十六计,这里的七十二变和三十六计里的每一个变法和计谋,都是一种策略。需要当事者根据具体的情形,去做选择变成什么和使用哪一个计谋。
1. 策略模式类图
2. 策略模式的组成:
抽象策略基类、策略实现类、调用者。
基类中有抽象的算法,实现类实现具体和算法行为,调用者类持有策略接口的引用,可以灵活调用不同实现类的策略。
3. design example
以外出旅行为例,有各种不同的旅行方式。
策略抽象基类
/**
* 策略抽象基类, 具有抽象行为接口
*/
public interface TravelStrategy {
public void travel();
}
实现类:骑行旅行
public class BikeTravel implements TravelStrategy {
@Override
public void travel() {
System.out.println("Travel by Bike.");
}
}
实现二:火车旅行
public class RailWayTravel implements TravelStrategy {
@Override
public void travel() {
System.out.println("Travel by RailWay.");
}
}
实现三:徒步旅行
public class WalkTravel implements TravelStrategy {
@Override
public void travel() {
System.out.println("Travel by Walk.");
}
}
调用者类:旅客
/**
* 策略调用类, 持有策略的引用
*/
public class Person {
private Long id;
private String name;
private TravelStrategy strategy;
public void setStrategy(TravelStrategy strategy) {
this.strategy = strategy;
}
public void travel() {
strategy.travel();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
测试类:
public class InvokeClient {
public static void main(String[] args) {
Person person = new Person();
person.setStrategy(new WalkTravel());
person.travel();
person.setStrategy(new BikeTravel());
person.travel();
person.setStrategy(new RailWayTravel());
person.travel();
}
}
使用策略模式,可以更好地根据不同的情况,做出更适合的应对策略。
优点:
封装算法,降低了算法的使用者和算法之间的耦合度,做好了良好的解耦。
体现了对扩展开放,对修改关闭的设计原则,使程序有更好的可维护性和扩展性。
面向抽象编程,而不是面向具体编程,使系统具有了灵活性。
缺点:
调用者需要知道每一种策略,才能正确地使用策略,要求调用者需要掌握每一种策略的使用场景。
对每一种变化都做了封装策略类,使系统中的类的数量增加,增加了系统的复杂度。
使用场景:
1.替代诸多if..else..条件判断。
2.算法需要自由切换。
3.多个类只在某些行为或算法上有所不同。
使用对象:
可以是一个对象使用多种策略,也可以是不同的对象使用不同的策略,依情形而定。
注意事项:
当策略过多时,会增加系统的复杂度,需要考虑策略膨胀的问题。