文章内容
一、什么是策略模式
策略模式,定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。
策略模式,属于对象行为型模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派诶不同的对象对这些算法进行管理。
二、策略模式类图

三、策略模式角色
- 抽象策略角色(Strategy): 定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
- 具体策略角色(ConcreteStrategy):实现了抽象策略定义的接口,提供具体的算法实现。
- 环境角色(Context): 持有一个策略类的引用,最终给客户端调用。
四、策略模式优缺点
1、优点
- 避免出现多重条件语句,更易维护。
- 提供一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
- 可以提供相同行为的不同实现,客户可以根据需要自行选择。
- 新增算法时,不会修改原有代码,满足开闭原则。
- 把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者分离。
2、缺点
- 客户端必须理解所有策略算法,以便选择恰当的算法类。
- 产生了很多的策略类,一定程度上增加了维护难度。
五、策略模式demo示例
1、Demo需求
下班了,乘坐什么交通工具回家呢?可以选择打车、坐地铁、乘公交,请使用策略模式实现此需求。
2、代码实现
1 2 3 4 5 6 7 8 | /** * 抽象策略角色:下班回家乘坐交通工具 */ public abstract class Transportation { /** * 回家乘坐交通工具 */ public abstract void goHome(); } |
1 2 3 4 5 6 7 8 9 | /** * 具体策略角色:出租车 */ public class TaxiTransportation extends Transportation { @Override public void goHome() { System.out.println( "下班,打出租车回家" ); } } |
1 2 3 4 5 6 7 8 9 | /** * 具体策略角色:地铁 */ public class SubwayTransportation extends Transportation { @Override public void goHome() { System.out.println( "下班,乘坐地铁回家" ); } } |
1 2 3 4 5 6 7 8 9 | /** * 具体策略角色:公交车 */ public class BusTransportation extends Transportation { @Override public void goHome() { System.out.println( "下班,乘公交车回家" ); } } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | /** * 环境角色:下班回家乘坐交通工具 */ public class OffDutyContext { private Transportation transportation; public void setTransportation(Transportation transportation) { this .transportation = transportation; } /** * 回家啦 */ public void go() { transportation.goHome(); } } |
3、测试
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | /** * 策略模式-客户端测试类 */ public class Client { public static void main(String[] args) { OffDutyContext offDuty = new OffDutyContext(); // 1.乘坐出租车回家 offDuty.setTransportation( new TaxiTransportation()); offDuty.go(); System.out.println( "==============================" ); // 2.乘坐地铁回家 offDuty.setTransportation( new SubwayTransportation()); offDuty.go(); System.out.println( "==============================" ); // 3.乘坐公交车回家 offDuty.setTransportation( new BusTransportation()); offDuty.go(); System.out.println( "==============================" ); } } |
控制台输出日志:
1 2 3 4 5 6 | 下班,打出租车回家 ============================== 下班,乘坐地铁回家 ============================== 下班,乘公交车回家 ============================== |