架构抽象层级混合问题:高层类同时引用中间层与底层是否可行?
架构设计疑问:高层类同时依赖中间层与底层的合理性分析
初始场景
我有一个处理核心业务的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仍直接调用底层方法。我想知道:
- 这种高层类同时依赖中间层和底层的做法是否可行?
- 有人认为应在中间层新增
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
相关产品推荐
相关产品推荐

