多态API设计核心是客户端只依赖契约而非实现:接口定义统一参数返回类型,Spring容器管理实现注入,行为差异封装在接口方法内,支持运行时插件化加载。

在 API 设计中用好多态,核心是让客户端只认“契约”,不认“谁干的”。客户端代码不感知具体实现类,也不因新增功能而修改,这才是真正降低耦合。
接口即契约:参数和返回值统一用接口类型
API 方法的入参、出参、异常包装全部基于接口或泛型抽象类型,而非具体实现类。这样客户端调用时,传什么实现、收什么实现,都由运行时决定,编译期完全解绑。
- 定义 PaymentService 接口,不暴露 WechatPayServiceImpl 或 AlipayServiceImpl 类名
- 控制器方法写成 public ResponseEntity<String> pay(@RequestBody Order order, PaymentService service),客户端可传任意合法实现
- 响应体用 ApiResponse<T> 泛型包装,避免返回 Object 或 Map 等弱类型,兼顾类型安全与复用性
注入即解耦:靠 Spring 容器管理实现切换
客户端不 new 实例、不硬编码类型判断,所有实现类交由容器托管,通过配置或注解动态绑定。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 为不同支付实现标注 @Service("wechat")、@Service("alipay")
- 用 @Autowired @Qualifier("wechat") PaymentService service 显式指定,或结合 @Value("${payment.type}") 配置驱动
- 避免在 Controller 或 Service 层写 if (service instanceof WechatPayService) —— 这等于主动破坏多态
行为即边界:把差异收进接口方法内部
接口方法签名要覆盖业务语义,不暴露实现细节。退款要不要证书、是否需异步回调,都由各实现类自己处理,上层无需知晓。
立即学习“Java免费学习笔记(深入)”;
- 在 PaymentService 中定义 refund(RefundRequest req),而非拆成 refundWithCert() 和 refundSimple()
- 新增银联支付只需新增一个实现类并注册 Bean,Controller、DTO、测试用例全都不动
- 若发现不得不加 instanceof 或强转,说明接口职责没划清,应回头重构方法签名
加载即透明:插件化支持运行时按需装配
对扩展性要求高的 API(如风控策略、消息渠道),可用字符串标识代替类名,配合工厂或 ServiceLoader 动态加载,彻底隔离编译依赖。
- 配置文件写 notification.channel=sms,加载器根据该 key 返回对应 NotificationChannel 实现
- 禁止在主流程中 import 具体插件类,所有插件实现放在独立 module 或 jar 包中
- 提供 isAvailable() 或健康检查钩子,失败时自动降级,不拖垮主链路

















