策略模式,顾名思义,是使用不同的策略解决问题的模式,孙悟空有七十二变,孙子兵法有三十六计,这里的七十二变和三十六计里的每一个变法和计谋,都是一种策略。需要当事者根据具体的情形,去做选择变成什么和使用哪一个计谋。
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.多个类只在某些行为或算法上有所不同。
使用对象:
可以是一个对象使用多种策略,也可以是不同的对象使用不同的策略,依情形而定。
注意事项:
当策略过多时,会增加系统的复杂度,需要考虑策略膨胀的问题。