设计模式之策略模式
策略(Strategy)模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法时的处理策略。简单来说,策略模式定义了一个算法家族,并让这些算法可以互换。
传统模式是通过继承处理多种算法或行为。该方式需要大量的子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。继承使得动态改变算法或行为变得不可能(每一个子类只能实现特定的算法)。
策略模式是对一系列算法的封装,即:为所有的算法定义一个抽象的算法接口(可以是接口,也可以是抽象类),并由具体的策略对象对算法进行实现。具体的算法选择交由具体策略类决定(具体策略类持有策略接口的引用)。
本模式的核心思想是:多态(面向接口编程),组合。【替代继承关系】
1. 传统模式【通过继承实现】
1.1 父类【Duck.java】
定义主要功能方法的通用实现。

public class Duck { public void swim() { System.out.println("I can swim."); } }
1.2 继承对象类
实现自己的特有逻辑

public class FreeStrokeDuck extends Duck { @Override public void swim() { System.out.println("I can free stroke."); } } public class BreaststrokeDuck extends Duck { @Override public void swim() { System.out.println("I can breaststroke."); } }
1.3 Demo

public static void main(String[] args) { Duck duck = new FreeStrokeDuck(); duck.swim(); }
2. 策略模式
将对象分为三种角色:1.抽象策略角色,2.具体策略角色,3.环境角色
2.1 抽象策略角色
为算法定义一个抽象的算法接口

public interface Duck { void swim(); }
2.2 具体策略角色
实现抽象策略角色,根据具体的业务需求,实现特定的算法

public class FreeStrokeDuck implements Duck{ @Override public void swim() { System.out.println("I can free stroke."); } } public class BreaststrokeDuck implements Duck { @Override public void swim() { System.out.println("I can breaststroke."); } }
2.3 环境角色
策略的外部封装类,或者说策略的容器类。根据不同策略执行不同的行为。

public class Skill { //策略角色的引用,多态原理 Duck duck; public Skill(Duck duck) { this.duck = duck; } public void swim() { duck.swim(); } }
2.4 Demo

/** * 避免接口对外暴露后被篡改 */ public static void main(String[] args) { Skill skill = new Skill(new FreeStrokeDuck()); skill.swim(); }
3. 枚举+ lambda表达式
3.1 定义策略角色

public interface Skill { void swim(); }
3.2 创建枚举类

public enum SkillEnum { /** * 使用lamda表达式实现Skill接口 */ FREE_SKROKE(() -> { System.out.println("I can free stroke."); }), BREAST_STROKE(() -> { System.out.println("I can breaststroke."); }); private Skill skill; SkillEnum(Skill skill) { this.skill = skill; } public Skill getSkill() { return skill; } }
3.3 创建环境角色

public class Duck { private SkillEnum skill; public Duck(SkillEnum skill) { this.skill = skill; } public void swim() { skill.getSkill().swim(); } }
3.4 Demo

public static void main(String[] args) { Duck duck = new Duck(SkillEnum.BREAST_STROKE); duck.swim(); }
4. 补充
4.1 继承是在编译时静态决定类的行为,组合是在运行时动态地拓展对象的行为。而且,通过动态地组合对象,可以写新的代码添加新功能,而无须修改现有的代码(出现Bug的概率会变低)。
5. 参考资料
5.1 北风网在线培训《策略模式》
5.2 百度百科《策略模式》
5.3 O'Reilly《Head First设计模式》
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix