要接入十几家支付渠道,每家流程相似但细节不同,你会用接口、抽象类还是组合来设计?
我的判断
支付渠道我会以接口定义能力、用组合编排共性流程,只有确实存在稳定骨架时才放一层很薄的抽象类。
我不会让十几个渠道都继承一个几千行的 AbstractPayment。先定义小接口,例如 createPayment、queryPayment、refund,每个渠道适配自己的签名、字段和错误码;统一流程由一个编排器组合幂等校验、渠道路由、请求落库、调用、结果转换和监控。
interface PaymentChannel {
PayResult pay(PayCommand command);
QueryResult query(String channelOrderNo);
}
组合的好处是重试、签名器、HTTP 客户端、限流器可以单独替换和测试。某几家渠道如果确实共享固定的“组装请求—发送—验签—转换”骨架,可以用抽象类提供模板方法,但渠道差异仍通过受保护的扩展点注入,不能在父类里堆渠道判断。
接入新渠道的验收不是只跑通成功路径,还会覆盖重复请求、超时后查单、回调乱序、退款部分成功和密钥轮换。设计是否合理,看新增一家渠道要改多少旧代码,而不是用了多少设计模式。
容易答偏踩坑误区
- 用一个大接口要求所有渠道实现全部能力。 不支持分账的渠道只能抛异常,能力边界会越来越模糊。
- 把重试写进渠道实现。 支付超时可能已经受理,正确动作通常是先查单。
- 父类里出现大量渠道 if/else。 这说明继承已经没有提供稳定抽象。