多态的核心是用统一接口适配多种实现,避免硬编码分支。如支付渠道、消息推送、规则引擎、UI渲染等场景,均通过定义接口、各子类封装差异逻辑、运行时动态调用,实现新增类型零修改主流程。

多态在实际项目开发中,核心是让同一段调用逻辑能适配多种具体实现,避免硬编码分支,提升可扩展性和可维护性。它不是炫技,而是解决“新增一种类型就得改主流程”这类高频痛点的务实手段。
支付渠道统一调度
电商或SaaS系统常需接入微信、支付宝、PayPal、银行卡等多种支付方式。每种渠道的签名规则、回调验签、异步通知处理逻辑完全不同,但上层订单服务只关心“发起支付”和“处理回调”两件事。
- 定义接口 PaymentProcessor,声明
pay(PaymentRequest req)和handleNotify(Map<string string> params)</string> - 每个渠道实现该接口:WechatProcessor、AlipayProcessor、StripeProcessor,各自封装平台专属逻辑
- 网关 Controller 接收 channel 参数,通过 Spring 的
@Qualifier或策略工厂获取对应 Bean,直接调用接口方法 - 新增 Apple Pay 支付?只需写一个新实现类 + 注册 Bean,订单服务和网关代码零修改
消息推送渠道适配
用户通知可能走短信、站内信、企业微信、飞书、邮件等不同通道,模板格式、发送限频、失败重试策略各不相同,但业务方只希望调用 notify(user, templateId, data)。
- 抽象出 NotificationService 接口,统一输入(用户标识、内容上下文)、统一输出(是否送达、错误码)
- 子类 SmsService、FeishuService、EmailService 分别对接各自 SDK,处理认证、模板渲染、发送重试
- 通知中心根据用户偏好配置(如“重要消息走企微+短信”),动态组合多个 NotificationService 实例并行调用
- 运营后台新增钉钉通知?加个 DingTalkService 就完事,不用动任何调度逻辑
规则引擎行为解耦
风控初筛、优惠券匹配、分润计算等场景,规则越来越多,若用 if-else 或 switch 硬写,每次加规则都要改核心方法,极易出错且无法单元测试。
- 定义 Rule 接口:含
match(Context ctx)(判断是否命中)和execute(Context ctx)(执行动作) - 每条规则独立成类:HighRiskIpRule、NewUserCouponRule、TieredCommissionRule
- 引擎主流程只做一件事:遍历所有已注册 Rule 实例,对每个调用
match(),命中则调execute() - 上线新规则?写类 → 加 @Component → 配置启用开关,主引擎完全无感
UI 组件动态渲染(移动端/前端通用思路)
信息流、表单、后台配置页常需根据数据类型动态展示不同 UI,比如同一份 JSON 数据里有文本块、图片、视频、投票组件。
- 定义基类或协议 Renderable,声明
getViewType()和bindTo(view: View) - 每个模块实现自己的 Renderer:TextViewRenderer、ImageViewRenderer、PollViewRenderer
- 列表 Adapter 拿到数据列表后,根据 item 的 type 创建对应 Renderer,调用 bindTo 渲染即可
- 产品提需求:“增加音频播放卡片”?前端/客户端各加一个 AudioRenderer,列表逻辑一行不动
多态落地的关键不在语法,而在设计意识:当发现代码里反复出现“根据 type 字段做 if 判断再调不同方法”,就是多态该出手的时候。把变化点封装进子类,把稳定契约留在接口,系统就自然具备了“插拔式扩展”的能力。

















