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

架构抽象层级混合问题:高层类同时引用中间层与底层是否可行?

架构设计疑问:高层类同时依赖中间层与底层的合理性分析

初始场景

我有一个处理核心业务的HighBusinessLogic类:

public class HighBusinessLogic{
  public void DoBusiness1(){
  }
  public void DoBusiness2(){
  }
  public void DoBusiness3(){
  }
}

该类依赖底层业务逻辑类LowBusinessLogic完成具体操作:

public class HighBusinessLogic{
  private LowBusinessLogic _lowBusinessLogic;

  public HighBusinessLogic(LowBusinessLogic lowBusinessLogic){
    _lowBusinessLogic = lowBusinessLogic;
  }

  public void DoBusiness1(){
    // some code
    _lowBusinessLogic.DoThing(someData);
    // some other code
  }
  public void DoBusiness2(){
    // some code
    _lowBusinessLogic.DoThing(someData);
    // some other code
  }
  public void DoBusiness3(){
    // some code
    _lowBusinessLogic.DoAnotherThing(someData);
    // some other code
  }
}

需求变更:新增重复前置逻辑

实际场景中,调用_lowBusinessLogic.DoThing前需要重复执行相同的数据处理逻辑DoStuffWithData,代码变成:

public class HighBusinessLogic{
  private LowBusinessLogic _lowBusinessLogic;

  public HighBusinessLogic(LowBusinessLogic lowBusinessLogic){
    _lowBusinessLogic = lowBusinessLogic;
  }

  public void DoBusiness1(){
    // some code
    DoStuffWithData(someData);        // 重复逻辑
    _lowBusinessLogic.DoThing(someData);
    // some other code
  }
  public void DoBusiness2(){
    // some code
    DoStuffWithData(someData);      // 重复逻辑
    _lowBusinessLogic.DoThing(someData);
    // some other code
  }
  public void DoBusiness3(){
    // some code
    _lowBusinessLogic.DoAnotherThing(someData);
    // some other code
  }
}

我的解决方案:引入中间层

为了消除重复代码,我考虑新增中间抽象层IntermediateBusinessLogic,封装DoStuffWithData和DoThing的组合逻辑:

public class IntermediateBusinessLogic{
  private LowBusinessLogic _lowBusinessLogic;

  public IntermediateBusinessLogic(LowBusinessLogic lowBusinessLogic){
    _lowBusinessLogic = lowBusinessLogic;
  }

  public void DoStuffWithDataAndDoThings(Data someData){
    DoStuffWithData(someData);
    _lowBusinessLogic.DoThing(someData);
  }
}

public class HighBusinessLogic{
  private LowBusinessLogic _lowBusinessLogic;
  private IntermediateBusinessLogic _intermediateBusinessLogic;

  public HighBusinessLogic(
    LowBusinessLogic lowBusinessLogic,
    IntermediateBusinessLogic intermediateBusinessLogic)
  {
    _lowBusinessLogic = lowBusinessLogic;
    _intermediateBusinessLogic = intermediateBusinessLogic;
  }

  public void DoBusiness1(){
    // some code
    _intermediateBusinessLogic.DoStuffWithDataAndDoThings(someData);
    // some other code
  }
  public void DoBusiness2(){
    // some code
    _intermediateBusinessLogic.DoStuffWithDataAndDoThings(someData);
    // some other code
  }
  public void DoBusiness3(){
    // some code
    _lowBusinessLogic.DoAnotherThing(someData);
    // some other code
  }
}

核心疑问

但这样出现了抽象层级混合的问题:DoBusiness3仍直接调用底层方法。我想知道:

  1. 这种高层类同时依赖中间层和底层的做法是否可行?
  2. 有人认为应在中间层新增DoAnotherThing方法转发底层调用,但这会导致中间层接口方法泛滥,违反SOLID原则。那么同一个类同时引用中间层和底层是否存在实质性问题?除了“代码不整洁”之外,还有哪些潜在问题?

分析与解答

1. 这种做法是否可行?

短期来看完全可行,能解决当前重复代码的问题,且不会影响现有功能的运行。但从长期维护角度,需要评估潜在风险。

2. 实质性问题与潜在风险

除了代码整洁度的问题,还存在以下核心风险:

  • 分层边界模糊,违背架构设计初衷:分层架构的核心是隔离关注点,高层应只依赖对应抽象层而非直接跳过层级访问底层。这种混合依赖会让层级边界逐渐模糊,后续新需求加入时,其他开发者可能随意在高层直接调用底层方法,导致分层设计彻底失效。
  • 底层变更的维护成本剧增:如果LowBusinessLogic的DoAnotherThing方法签名或逻辑变更,原本只需修改中间层的统一转发逻辑(若中间层封装了所有底层调用),现在需要直接修改HighBusinessLogic。随着依赖底层的高层类数量增加,底层变更的影响范围会指数级扩大。
  • 测试复杂度提升:测试HighBusinessLogic时,需要同时模拟LowBusinessLogic和IntermediateBusinessLogic两个依赖,测试用例的准备和维护成本更高。而且如果后续中间层需要对DoAnotherThing做统一增强(比如新增前置校验),还需要修改HighBusinessLogic的调用逻辑,违背开闭原则。
  • 职责边界膨胀:HighBusinessLogic的职责是处理核心业务流程,现在它既依赖中间层的组合逻辑,又直接操作底层细节,会导致其职责膨胀,后续难以拆分和维护。

更优替代方案

与其让高层混合依赖,不如换一种方式消除重复代码:

  • 方案一:将DoStuffWithData封装为工具类:如果DoStuffWithData是纯数据处理逻辑,不依赖业务状态,可以封装成静态工具类,在DoBusiness1和DoBusiness2中直接调用,无需新增中间层。
  • 方案二:使用装饰器模式增强底层逻辑:创建LowBusinessLogicDecorator,在DoThing方法中自动执行DoStuffWithData,这样HighBusinessLogic无需修改,直接依赖装饰后的LowBusinessLogic即可。示例代码:
public class LowBusinessLogicDecorator implements LowBusinessLogic {
    private LowBusinessLogic _original;

    public LowBusinessLogicDecorator(LowBusinessLogic original) {
        _original = original;
    }

    @Override
    public void DoThing(Data someData) {
        DoStuffWithData(someData);
        _original.DoThing(someData);
    }

    @Override
    public void DoAnotherThing(Data someData) {
        _original.DoAnotherThing(someData); // 直接转发,无需额外逻辑
    }
}

这种方式既保持了分层的清晰性,又消除了重复代码,同时符合开闭原则——后续如果需要新增其他前置/后置逻辑,只需新增装饰器即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 04:18:16