核心是将类型判断与行为绑定分离:工厂负责判断,实现类负责行为;接口方法签名必须统一;工厂需启动时注册;有状态策略不可单例;新增渠道只需添加带注解的实现类并确保扫描,符合开闭原则。

核心不是“用了多态”,而是把类型判断和行为绑定彻底分开:判断交给工厂,行为交给实现类。主流程里只留一句 handler.handle(),所有分支逻辑消失不见。
接口定义要统一、方法签名必须一致
所有策略实现类必须实现同一个接口,且方法参数、返回值完全相同。比如:
- 不能一个
send(String msg),另一个send(String msg, String userId) - 不能一个返回
void,另一个返回Result - 否则调用方无法无差别调用,多态就失效了
工厂注册要提前、拒绝运行时反射
别在每次请求时用 Class.forName().newInstance()——JDK9+ 默认禁用,出错难定位。正确做法是启动时扫描并注册:
- 用
@HandlerType("email")注解标记每个实现类 - Spring 启动时自动收集,存入
Map - 运行时直接
handlers.get(type),为空就明确抛异常,不静默失败
实例生命周期要看状态、别乱用单例
无状态策略(纯计算、无缓存、无 ThreadLocal)可复用单例;但只要带字段,比如:
private Mapcache = new HashMap(); private final ThreadLocalctx = ThreadLocal.withInitial(...);
就必须每次新建,或交由工厂按需创建。Spring 的 @Scope("prototype") 可用,但注意它不自动销毁,也不调 @PreDestroy。
新增渠道不用改老代码、符合开闭原则
加一个新渠道(比如 “whatsapp”),只需三步:
- 写新实现类,实现同一接口,加上
@HandlerType("whatsapp") - 确保类被 Spring 扫描到(如加
@Component) - 重启后自动注册进工厂 Map,主流程无需任何修改
不用动 if-else,不改 switch,不碰常量类,真正实现“对扩展开放,对修改关闭”。










