策略模式通过统一接口与多实现类实现多态,用Map动态路由避免if-else,工厂负责类型识别,策略专注行为,新增类型只需添加带注解的实现类,符合开闭原则。

多态本身不是目的,而是让调用方完全不感知具体类型。策略模式是把多态落地最直接的方式——它把“判断该用哪个逻辑”和“执行什么逻辑”彻底分开,从而根除 if-else 的硬编码分支。
统一接口 + 多个实现类
定义一个清晰的行为接口,比如 Handler,只声明一个方法:handle(Request req)。所有业务变体(如 EmailHandler、SmsHandler、WechatHandler)都实现这个接口,各自封装内部逻辑。关键点是:方法签名必须完全一致——参数类型、数量、返回值都不能有差异,否则调用方无法无差别调用,多态就失效了。
运行时动态路由,不写 if-else
用 Map<String, Handler> 或 Map<Class<?>, Handler> 存储所有策略实例,key 是类型标识(如 "email"、"sms"),value 是对应实现类的实例。启动时完成注册(例如 Spring 中用 @PostConstruct 扫描带 @HandlerType 注解的 Bean),避免每次请求都反射创建对象。主流程里只需一句:handlers.get(type).handle(req),没有分支,没有判断。
工厂负责识别,策略专注行为
类型识别逻辑(比如从请求中提取 type 字段、解析枚举、匹配字符串)应集中在工厂或上下文类中,而不是散落在各处。策略实现类只做一件事:执行自己的业务逻辑。新增一种类型时,只需:
立即学习“Java免费学习笔记(深入)”;
- 写一个新的 Handler 实现类
- 加上 @HandlerType("new_type") 注解
- 确保被 Spring 扫描到
无需修改任何已有代码,也不动老的 if-else,真正符合开闭原则。
避开常见陷阱
不要在接口里加 getType() 方法,然后外面再写 if (h.getType() == X) ——这等于把 if-else 搬到了别处,还是需要改调用方;不要让策略类持有共享状态(如缓存 Map、ThreadLocal)还当成单例复用,有状态的策略应按需创建;别在运行时用 Class.forName 动态加载,JDK9+ 默认禁用,出错难排查。


















