明确扩展点接口需用抽象类定义行为契约,如PaymentPlugin强制子类实现supports()和execute();父类提供日志、幂等校验等模板方法,子类仅专注差异化逻辑;通过类加载隔离与元数据驱动实现运行时动态插拔;调用端依赖多态,无需类型判断。

明确扩展点接口,用抽象类定义行为契约
可插拔组件不是随便加个继承就能实现的,关键在顶层抽象是否清晰表达了“它该做什么”。推荐用抽象类而非普通父类,强制子类实现核心逻辑。比如支付模块,定义 abstract class PaymentPlugin,包含 abstract boolean supports(String channel) 和 abstract void execute(Order order)。这样所有子类(AlipayPlugin、UnionPayPlugin)都必须回答“支持哪些渠道”和“怎么执行”,阅读代码时一眼可知能力边界。
让子类只专注差异化逻辑,复用由父类统一提供
父类负责兜底通用能力,子类只写真正不同的部分。例如在 PaymentPlugin 中预置日志记录、幂等校验、异常包装等模板方法,子类只需重写 doExecute();又如组织架构场景中,OrganizationUnit 提供通用审批流程骨架,Department 重写 budgetCheck() 加入额度限制,EngineeringTeam 再重写加入CTO确认环节——每层只叠加一层语义,不重复、不越界。
通过类加载隔离 + 元数据驱动实现动态插拔
真正的可插拔意味着运行时能启用或停用,而不是编译期写死。每个插件 JAR 包内带 META-INF/plugin.yml,声明 id、version、provides: [PaymentPlugin]、requires: [com.example.common]。主系统用 PluginClassLoader(继承 SecureClassLoader)加载,避免类冲突;通过 PluginManager.enable("alipay-plugin") 触发 init() → start() 流程,注册到策略路由 Map;调用 disable() 时只 stop() 释放资源,不卸载类,规避 ClassCastException 风险。
用多态替代类型判断,保持调用端干净
业务代码不该出现 if-else 判断插件类型。统一用父类或接口引用,比如 PaymentPlugin plugin = pluginManager.getPlugin(channel),然后直接调用 plugin.execute(order)。背后由多态机制自动绑定到具体子类实现。这样新增一个插件,只要实现抽象类、打包、配置元数据,业务侧完全无感,也不用改任何 switch 或 instanceof 逻辑。
立即学习“Java免费学习笔记(深入)”;


















