不修改基类变更行为:类A的foo方法扩展设计模式问询
用策略模式完美解决你的需求
绝对可以!你描述的场景正好适配策略模式(Strategy Pattern),既能满足不修改类A、不改动现有业务代码的要求,还能轻松扩展后续的类C、D。我给你一步步讲怎么实现:
1. 抽象出公共接口
首先把类A的foo()方法抽象成一个接口,这样现有代码可以通过接口来依赖,而不是直接依赖类A——这一步是为后续替换策略做铺垫,而且完全不需要修改类A的代码:
// 定义接口,对应你的InterfaceA public interface InterfaceA { // 替换成你实际的参数类型和返回类型 YourReturnType foo(YourParamType params); } // 让原类A实现这个接口,原代码完全不用改 public class A implements InterfaceA { @Override public YourReturnType foo(YourParamType params) { // 这里保留类A原本的foo()逻辑,一行都不用动 } }
2. 创建自定义策略类(比如类B)
针对bar的特定值,创建一个新的类B实现InterfaceA。这里推荐用组合而非继承的方式,直接复用类A的逻辑,避免复制粘贴代码:
public class B implements InterfaceA { // 持有原类A的实例,复用它的基础逻辑 private final InterfaceA originalA; // 通过构造器注入原实例,保证灵活性 public B(InterfaceA originalA) { this.originalA = originalA; } @Override public YourReturnType foo(YourParamType params) { // 判断是否是特定的bar值 if (isTargetBarValue(params.getBar())) { // 这里写你需要的自定义逻辑,返回不同结果 return generateCustomResult(params); } // 其他情况直接复用类A的逻辑 return originalA.foo(params); } // 判断bar是否为目标值的辅助方法 private boolean isTargetBarValue(BarType bar) { return bar.equals(/* 你的特定值 */); } // 生成自定义结果的方法 private YourReturnType generateCustomResult(YourParamType params) { // 自定义逻辑实现 } }
3. 用工厂类管理策略选择
创建一个工厂类,根据传入的bar值自动选择对应的策略实例。这样现有代码只需要从工厂获取InterfaceA实例,完全不用关心底层用的是A、B还是后续的C、D:
public class AStrategyFactory { // 提前初始化好各个策略实例,避免重复创建 private static final InterfaceA ORIGINAL_STRATEGY = new A(); private static final InterfaceA B_STRATEGY = new B(ORIGINAL_STRATEGY); // 后续新增类C、D时,只需要在这里添加对应的实例即可 public static InterfaceA getStrategy(YourParamType params) { // 根据bar值选择策略 if (isTargetBarValue(params.getBar())) { return B_STRATEGY; } // 后续可以添加更多判断,返回C、D等策略 return ORIGINAL_STRATEGY; } // 复用判断逻辑,也可以抽成公共工具类 private static boolean isTargetBarValue(BarType bar) { return bar.equals(/* 你的特定值 */); } }
4. 现有代码的改造(几乎无侵入)
原来的代码如果是直接new A().foo(params),现在只需要改成:
InterfaceA instance = AStrategyFactory.getStrategy(params); instance.foo(params);
如果你的现有代码已经通过依赖注入等方式获取类A的实例,那只需要把注入的对象换成工厂返回的InterfaceA实例,业务逻辑完全不用改动——完美符合你“继续使用A(或InterfaceA)、无需修改现有代码”的要求。
为什么这个方案适合你?
- 完全不修改类A:类A的代码原封不动,后续类A更新也不会影响你的自定义策略
- 对现有代码侵入极小:只需要替换获取实例的方式,业务逻辑不用改
- 扩展性极强:后续要加类C、D,只需要新增实现InterfaceA的类,然后在工厂里加一行判断即可,完全符合开闭原则
内容的提问来源于stack exchange,提问作者mt0s




