You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用策略设计模式时如何避免代码重复?求适配设计方案

消除策略模式重复代码的方案及模式选择

一、核心问题分析

你的三个Strategy类存在明显重复:

  • 成员变量重复:Helperclass1和Daoclass是三个类共有的,Helperclass2是StrategyA、B共有的
  • 执行流程重复:execute方法都包含helperclass1.method(obj)和dao.update(updatedObj)的步骤,StrategyA、B还多了helperclass2.method2的步骤

这种场景不需要放弃策略模式,结合模板方法模式就能完美解决代码冗余问题。

二、具体改造方案

1. 抽象基类提取通用逻辑

创建抽象基类AbstractStrategy,把重复的成员变量、固定执行流程放到基类中,仅将变化的部分定义为钩子方法(子类可选择性重写):

abstract class AbstractStrategy implements Strategy {
    protected final Helperclass1 helperclass1;
    protected final Daoclass dao;
    protected final Optional<Helperclass2> helperclass2;

    // 构造函数注入依赖,避免子类重复声明
    public AbstractStrategy(Helperclass1 helperclass1, Daoclass dao, Helperclass2 helperclass2) {
        this.helperclass1 = helperclass1;
        this.dao = dao;
        this.helperclass2 = Optional.ofNullable(helperclass2);
    }

    // 模板方法:固定执行流程,用final防止子类篡改
    @Override
    public final void execute(Object obj) {
        Object updatedObj = helperclass1.method(obj);
        updatedObj = applyHelper2(updatedObj);
        updatedObj = customUpdate(updatedObj);
        dao.update(updatedObj);
    }

    // 钩子方法:默认不处理(若helperclass2为空则直接返回原对象),子类无需重写即可复用
    protected Object applyHelper2(Object obj) {
        return helperclass2.map(Helperclass2::method2).orElse(obj);
    }

    // 钩子方法:默认返回原对象,仅需要自定义更新的子类重写
    protected Object customUpdate(Object obj) {
        return obj;
    }
}

2. 简化子类实现

每个子类只需要实现自身特有的逻辑,其余复用基类代码:

// StrategyA:仅重写自定义更新逻辑
class StrategyA extends AbstractStrategy {
    public StrategyA(Helperclass1 helperclass1, Helperclass2 helperclass2, Daoclass dao) {
        super(helperclass1, dao, helperclass2);
    }

    @Override
    protected Object customUpdate(Object obj) {
        // 这里实现StrategyA特有的对象更新逻辑
        return updatedObj;
    }
}

// StrategyB:无需重写任何方法,直接复用基类流程
class StrategyB extends AbstractStrategy {
    public StrategyB(Helperclass1 helperclass1, Helperclass2 helperclass2, Daoclass dao) {
        super(helperclass1, dao, helperclass2);
    }
}

// StrategyC:仅传入null作为helperclass2,自动跳过该步骤
class StrategyC extends AbstractStrategy {
    public StrategyC(Helperclass1 helperclass1, Daoclass dao) {
        super(helperclass1, dao, null);
    }
}

三、模式选择说明

1. 为什么选择模板方法+策略模式?

  • 策略模式负责封装不同的业务变体(比如StrategyA的自定义更新),保证灵活性;
  • 模板方法模式负责提取固定执行流程,消除重复代码;
  • 两者组合是处理“固定流程下的多变体”场景的经典方案,既保留策略的扩展性,又解决冗余问题。

2. 命令模式是否适用?

命令模式核心是将请求封装为对象,适合需要实现命令队列、撤销/重做、日志记录等场景,和你当前“流程变体”的需求匹配度不高,不推荐作为替代方案。

四、额外优化建议

  • 用Optional处理Helperclass2的可选性,避免空指针异常;
  • 构造函数注入依赖,提高代码的可测试性和扩展性;
  • 模板方法execute用final修饰,确保固定流程不被子类篡改。

内容的提问来源于stack exchange,提问作者Sai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:25:20