模板方法设计模式选型合理性及子类公共方法处理咨询
选型合理性分析
你的Template Method选型是合理的。因为核心逻辑generalMethod有固定执行流程(先执行firstMethod,再secondMethod,最后commonMethod),而流程中的firstMethod、secondMethod存在分支化的可变逻辑,正好匹配Template Method模式“定义算法骨架,将可变步骤延迟到子类实现”的核心思想,能有效把公共流程和可变逻辑解耦,避免大量if-else堆砌。
部分共享方法的处理建议
针对你提到的“部分子类共享方法但不适合放入顶层抽象类”的问题,给你两种实用方案:
方案1:基于接口的Mixin模式(适配Java环境)
把不同的共享方法封装成带默认实现的接口,让需要的子类实现对应接口,既避免顶层抽象类冗余,又能复用代码:
- 定义
Condition2AndDefaultShared接口,添加默认方法condition2AndDefaultCommonMethod(),让Condition2Template和DefaultTemplate实现这个接口; - 定义
Condition1AndDefaultShared接口,添加默认方法condition1AndDefaultCommonMethod(),让Condition1Template和DefaultTemplate实现这个接口; - 顶层抽象类
Template只保留所有子类都需要的公共逻辑(比如generalMethod骨架、commonMethod),以及firstMethod、secondMethod这类必须由子类实现的抽象方法。
这种方式利用Java 8+的接口默认方法特性,既满足代码复用,又不会让不需要这些方法的子类(比如Condition1Template、Condition1Condition2Template)被迫继承无用方法。
方案2:组合独立服务类(更灵活,符合依赖倒置)
把共享方法封装成独立的工具类/服务类,让需要的子类通过组合的方式调用,而非继承:
- 创建
Condition2DefaultService类,实现condition2AndDefaultCommonMethod(); - 创建
Condition1DefaultService类,实现condition1AndDefaultCommonMethod(); - 在
Condition2Template、DefaultTemplate中注入Condition2DefaultService实例,在需要的地方调用其方法; - 在
Condition1Template、DefaultTemplate中注入Condition1DefaultService实例,同理调用。
这种方式完全避免了继承带来的耦合,后续如果共享逻辑有变化,只需要修改服务类即可,子类无需调整,扩展性更强。
补充:Template Method的落地示例
结合你的伪代码,抽象类的核心结构可以这样写:
public abstract class Template { // 模板方法:固定执行流程,用final避免子类篡改 public final void generalMethod() { firstMethod(); secondMethod(); commonMethod(); } // 可变步骤:由子类实现具体逻辑 protected abstract void firstMethod(); protected abstract void secondMethod(); // 所有子类共享的公共方法 protected void commonMethod() { // 公共逻辑实现 } }
子类Condition1Template的示例实现:
public class Condition1Template extends Template implements Condition1AndDefaultShared { @Override protected void firstMethod() { condition1Method(); } @Override protected void secondMethod() { condition1AndDefaultCommonMethod(); } private void condition1Method() { // condition1对应的业务逻辑 } }
内容的提问来源于stack exchange,提问作者Jose Robles Villares
相关产品推荐
相关产品推荐

