主题切换
策略模式
一、基础定义
- 该模式定义一系列算法,将每个算法单独封装,算法之间可以互相替换;算法内部修改不会影响调用算法的客户端。
- 核心思想:对算法进行封装,把使用算法的业务逻辑和算法具体实现拆分,交给不同对象分别管理,解耦业务与算法。
- 示例场景:旅游出行,出行方式(自行车、汽车、火车、飞机)属于不同算法,可自由切换。
二、三大核心角色
- 抽象策略 Strategy 抽象角色,一般使用接口/抽象类实现,定义所有具体策略统一对外暴露的规范接口(本例为
travel()出行方法)。 - 具体策略 Concrete Strategy 实现抽象策略的接口,每一个类对应一套独立算法/行为;案例中bicycle、car、train、aircraft都是具体策略。
- 环境上下文 Context(TravelContext) 持有抽象策略对象引用,对外提供调用入口,客户端只和Context交互,由Context委托执行对应策略逻辑。
三、类图结构说明
- TravelContext:环境类,构造方法接收策略对象,提供
selectTravel()方法触发出行逻辑。 - Strategy:顶层抽象接口,定义
travel():void统一出行行为。 - 四个实现类bicycle/car/train/aircraft:分别实现travel方法,各自实现专属出行逻辑。
- 关联关系:Context聚合Strategy,多个具体策略实现抽象策略接口。
四、优缺点
优点
- 不同策略之间可以自由切换,运行时动态更换算法。
- 新增算法只需新增具体策略类,无需修改原有代码,符合开闭原则,易于扩展。
- 消除多层嵌套if-else/switch条件分支,把分支逻辑拆分到独立类,代码结构清晰,充分体现面向对象思想。
缺点
- 客户端必须知晓全部策略类,需要自己判断、选择使用哪一套策略。
- 业务算法较多时,会大量新增独立策略类,造成类文件数量膨胀。
五、完整总结(面试背诵版)
- 策略模式属于行为型设计模式,核心是封装一系列可互换的算法,拆分算法使用与算法实现逻辑,实现解耦。
- 包含抽象策略、具体策略、上下文环境三大角色;上下文持有策略引用,客户端通过上下文调用算法。
- 优势是消除ifelse、易扩展、动态切换策略;劣势是客户端需感知所有策略,算法多会产生大量策略类。
- 典型应用场景:支付方式选择、出行方案、优惠活动计算、文件解析器等多分支算法场景。
六、面试简答
问:介绍一下策略模式以及使用场景?
答: 策略模式封装一组独立可替换的算法,将算法实现与业务调用分离,包含抽象策略、具体策略、上下文三个角色。抽象策略定义统一接口,每个具体策略实现一套算法,上下文持有策略引用对外提供调用入口。 优点是消除多层ifelse、遵循开闭原则、运行时自由切换算法;缺点是客户端要清楚所有策略,算法多会产生大量类。 常用于多分支算法场景,比如多种支付方式、多种出行方案、不同折扣优惠计算等。