策略模式
- 定义
策略模式定义了一系列的算法,并将每一个算法都封装起来,使得每个算法可以互相替代,使算法本事和使用算法的客户端分割开来,相互独立。
初看策略模式的定义,似乎似懂非懂的感觉,我们需要一个具体的应用场景来对策略模式进行解释。
比如我们去旅行,我们可以选择很多路线,我们就可以把每一种路线看做是一种算法也就是一种策略。
- 策略模式类图
上图中可以看到,客户context有成员变量strategy或者其他的策略接口,也就说一个context可以指定多个策略,比如。旅行可以有路线的策略,还有花费的策略
- 代码实现
下面我们用策略模式代码实现旅行选择路线:
策略接口即旅行路线接口:
public interface Itinerary {
void path();
}
具体的路线即具体的算法:
public class YunnanPath implements Itinerary{
@Override
public void path() {
System.out.println("旅行路线是:广州-昆明-大理-丽江");
}
}
public class HunanPath implements Itinerary {
@Override
public void path() {
System.out.println("旅行路线是:广州-长沙-凤凰古城");
}
}
Context抽象类(抽象策略的上下文):
public abstract class Travel {
// 旅行路线,策略接口
protected Itinerary itinerary;
public Itinerary getItinerary() {
return itinerary;
}
public void setItinerary(Itinerary itinerary) {
this.itinerary = itinerary;
}
public abstract void travelPath();
}
具体的策略的上下文,也是具体算法的选择
public class CheapTravel extends Travel {
public CheapTravel() {
itinerary = new HunanPath();
}
@Override
public void travelPath() {
if (itinerary != null) {
itinerary.path();
}
}
}
public class ExpensiveTravel extends Travel {
public ExpensiveTravel() {
itinerary = new YunnanPath();
}
@Override
public void travelPath() {
if (itinerary != null) {
itinerary.path();
}
}
}
测试:
public class MyClient {
public static void main(String[] args) {
CheapTravel cheapTravel = new CheapTravel();
cheapTravel.travelPath();
ExpensiveTravel expensiveTravel = new ExpensiveTravel();
expensiveTravel.travelPath();
}
}
运行结果:
旅行路线是:广州-长沙-凤凰古城
旅行路线是:广州-昆明-大理-丽江
分析:
其实这个代码很简单,我们定义2个具体的路线,即相当策略模式定义里面2个算法。我们定义了一个Travel 抽象类,相当于策略上下文抽象类,ExpensiveTravel 和CheapTravel 相当于具体的策略上下文,负责和具体的策略实现交互,通常策略上下文对象会持有一个真正的策略实现对象,策略上下文还可以让具体的策略实现从其中获取相关数据,回调策略上下文对象的方法。
- 策略模式的作用:就是把具体的算法实现从业务逻辑中剥离出来,成为一系列独立算法类,使得它们可以相互替换。
- 策略模式的着重点:不是如何来实现算法,而是如何组织和调用这些算法,从而让我们的程序结构更加的灵活、可扩展。
- 策略模式的关键是:分析项目中变化部分和不变部分,把对象的行为抽象独立开来
- 策略模式的核心思想是:多用组合/聚合 少用继承;用行为类组合,而不是行为的继承。
- 策略模式缺点:没添加一个策略就要增加一个类,当策略过多时或导致类数目多大
总结:
- 策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。
- 在策略模式中,应当由客户端自己决定在什么情况下使用什么具体策略角色。2)
- 策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“退休”的方便,策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。这在一定程度上提高了系统的灵活性,但是客户端需要理解所有具体策略类之间的区别,以便选择合适的算法,这也是策略模式的缺点之一,在一定程度上增加了客户端的使用难度。
策略模式在JDK中应用
策略模式在JDK-Arrays应用。
- JDK的Arrays的Comparator就是使用了策略模式,即比较接口。大家可以查看源码分析.