【Day 2】层次架构在企业ERP中的设计
一、题目还原
题目场景:某大型制造企业计划升级其ERP系统,该系统覆盖采购管理、生产计划、库存管理、财务核算和人力资源五大核心模块。现有系统采用传统单体二层架构(客户端直接访问数据库),随着业务扩张已出现以下问题:①代码耦合严重,一次修改影响多个模块;②业务流程变更频繁,需求响应周期长达3个月;③安全性差,数据库连接直接暴露给客户端;④无法支撑多工厂分布式部署需求。系统架构师提出了基于层次架构风格的重构方案,将系统划分为表现层、业务逻辑层、数据访问层和基础设施层。
【问题1】(6分)请分别阐述严格分层与松散分层的区别,并结合该ERP系统的业务特点说明应选择哪种分层策略。
【问题2】(9分)针对上述分层架构,请设计层间通信策略,包括各层之间的调用方式、数据传输对象(DTO)的设计原则、以及层间解耦手段。
【问题3】(5分)在该ERP系统采用层次架构后,请分析其对质量属性可修改性和性能的影响,指出一个可能的权衡点。
【问题4】(5分)如果将该ERP系统的部分模块(如采购审批流程)改用事件驱动架构集成到现有分层架构中,请分析这种混合架构的优缺点。
二、考点分析
核心考点:层次架构风格——分层策略对比(严格分层 vs 松散分层)与层间通信设计。
答题模板:模板一(架构风格选择题+理由阐述)+ 模板四(系统设计/方案评价)
本题对应的答题框架:
- Q1:概念辨析型——先给出两种策略的定义,再结合案例选型+理由
- Q2:方案设计型——分层定通信方式 + DTO设计 + 解耦手段(至少3条)
- Q3:质量属性分析型——两个属性的影响分析 + 权衡点识别
- Q4:混合风格分析型——事件驱动的适用场景 + 优缺点分析
三、标准答案(采分点格式)
【问题1】严格分层 vs 松散分层(6分)
| 维度 | 严格分层(Strict Layering) | 松散分层(Relaxed Layering) |
|---|---|---|
| 定义 | 每一层只能调用其直接相邻下层的接口,不能跨层调用 | 允许上层访问非相邻下层的接口,跨层调用受控 |
| 层间可见性 | 仅可见相邻下层 | 可可见特定非相邻下层 |
| 耦合度 | 耦合度最低,修改影响局部化 | 耦合度中等,存在跨层依赖风险 |
| 性能开销 | 较高(层层透传增加调用链) | 较低(可绕开中间层直接访问) |
| 维护性 | 高,修改某层接口不影响上层以外 | 中,跨层调用可能产生连锁影响 |
选型决策:建议采用严格分层为主、有限放宽的混合策略。
理由(结合ERP业务):
①采购管理模块(业务逻辑复杂,变更频繁)→ 严格分层,确保可修改性优先;
②报表查询场景(高频读取,纯展示数据)→ 有限放宽,允许表现层绕过业务层直接调用数据访问层的只读查询接口,降低响应延迟;
③财务核算模块(安全性要求极高,有合规审计要求)→ 必须严格分层,所有请求经过完整的业务校验和数据权限控制;
④多工厂部署需求→ 严格分层便于将各层独立部署到不同服务器,实现分布式扩展。
【问题2】层间通信策略设计(9分)
(1)调用方式设计(4分)
| 调用方向 | 通信方式 | 技术选型 | 说明 |
|---|---|---|---|
| 表现层→业务层 | 同步RPC调用 | Spring Cloud OpenFeign / Dubbo | 请求-响应模式,事务一致性要求高的场景 |
| 业务层→数据访问层 | 接口调用(SPI) | MyBatis Mapper 接口 / JPA Repository | 通过IoC注入接口实现,业务层依赖抽象而非实现 |
| 业务层→基础设施层 | 异步消息 | RabbitMQ / RocketMQ | 日志记录、审计、通知等非核心链路 |
| 跨服务通信 | 事件驱动(可选) | Spring Cloud Stream + Kafka | 模块间解耦,如采购审批完成后触发库存更新 |
(2)DTO设计原则(3分)
| 原则 | 说明 | ERP示例 |
|---|---|---|
| 每层独立DTO | 各层使用独立的数据传输对象,不共享DO | 表现层用OrderVO、业务层用OrderDTO、数据层用OrderPO |
| DTO仅含所需字段 | 不给上层暴露不需要的数据 | 业务层返回给表现层的DTO不包含数据库自增ID、内部状态码 |
| 使用转换器(Assembler) | 层间通过Assembler进行DO↔DTO转换 | OrderAssembler.toDTO(orderPO)封装转换逻辑 |
(3)层间解耦手段(2分)
①依赖倒置原则(DIP):上层定义接口,下层实现接口,依赖关系指向抽象而非具体实现。例如:业务层定义IOrderRepository接口,数据访问层提供MyBatisOrderRepository实现。
②控制反转(IoC):通过Spring容器管理依赖注入,运行时装配具体实现。切换数据库访问框架时只需替换Bean实现,业务层代码无需修改。
③防腐层(ACL):在层边界处放置适配器,将下层变化隔离在上层之外。例如:当底层从MySQL迁移到TiDB时,数据访问层接口不变,只需替换内部实现。
【问题3】质量属性分析(5分)
对可修改性的影响(正向,2分):
- 关注点分离:每层职责明确,修改财务核算的规则只需修改业务逻辑层,不影响表现层和数据层
- 局部化修改:采购模块的审批流程变更只需修改采购业务服务,不会波及库存管理
- 接口稳定:定义清晰的层间契约,新增业务功能只需新增接口实现,遵循"开闭原则"
对性能的影响(负向,2分):
- 调用链加长:一个简单查询需要经过表现层→业务层→数据访问层→数据库,经过多层对象转换和参数校验
- 序列化开销:层间DTO转换涉及对象拷贝和序列化/反序列化,增加CPU和内存开销
- 网络延迟:分布式部署时,跨层调用变为远程RPC,增加网络RTT
权衡点(1分):
可修改性 vs 性能:严格分层增强了可修改性(模块独立、变更隔离),但每一次请求必须经过完整的层次栈,增加了调用链长度和对象转换开销。这是一个典型的权衡点——架构师需根据具体场景选择策略:对核心交易链路(如订单创建)采用严格分层保证可维护性,对高并发查询场景(如库存查询)适当放宽分层规则或引入缓存层减少调用次数。
【问题4】事件驱动+层次结构的混合架构(5分)
优点(3分):
①异步解耦:采购审批完成后发布"审批通过事件",库存模块、财务模块异步订阅处理,无需同步等待,提升系统吞吐量。
②可扩展性强:新增审计模块只需订阅相关事件,无需修改现有代码(符合开闭原则)。
③削峰填谷:审批流程在ERP中通常有业务高峰期(如月末集中审批),事件队列可缓存洪峰请求,避免后端过载。
缺点(2分):
①数据一致性降低:异步事件可能导致最终一致性问题。例如:采购审批通过但库存扣减失败,需要引入Saga或补偿事务机制。
②调试复杂度增加:事件流链路难以追踪,需要引入分布式链路追踪(如SkyWalking)和事件溯源机制。
③消息中间件成为新依赖:系统可用性依赖于消息中间件的稳定性,需部署集群和副本机制保证高可用。
四、评分要点
| 题号 | 分值 | 必备采分点(答出即可得分) | 加分项 |
|---|---|---|---|
| Q1 | 6分 | ① 说清严格分层的定义(只能调用相邻下层)【1分】 ② 说清松散分层的定义(允许跨层调用)【1分】 ③ 给出选型结论并会结合ERP业务提出差异化策略【2分】 ④ 至少给出1个具体模块的分层策略理由【1分】 | 提及财务模块需要严格分层以保证安全审计合规 +0.5分 |
| Q2 | 9分 | ① 设计了至少2种层间通信方式【2分】 ② 给出了DTO设计原则,提到了独立DTO或转换器【2分】 ③ 给出了至少2种解耦手段【2分】 ④ 有具体的技术选型(如Spring、MyBatis)【1分】 | 提到传输对象模式(TO)、防腐层(ACL)+0.5分 提到异步消息+同步RPC双通道设计 +0.5分 |
| Q3 | 5分 | ① 正面分析可修改性(每层独立修改、接口稳定)【1.5分】 ② 负面分析性能(调用链加长、对象转换开销)【1.5分】 ③ 明确指出"可修改性 vs 性能"是权衡点【1分】 | 提出针对不同场景采用不同分层策略的差异化方案 +1分 |
| Q4 | 5分 | ① 给出混合架构方案描述【1分】 ② 分析至少2个优点【2分】 ③ 分析至少2个缺点或应对措施【2分】 | 提到分布式事务(Saga)+0.5分 提到事件溯源(Event Sourcing)+0.5分 |
扣分项:
- 空谈理论不结合ERP业务场景 → 扣30%
- 混淆严格分层与松散分层的定义(说反了)→ Q1不得分
- 将层间通信等同于"直接方法调用"不考虑DTO解耦 → 扣1分
- 未识别权衡点 → 扣1分
五、扩展知识点
🔗 层次架构 vs 微服务架构(补充对照)
| 维度 | 层次架构 | 微服务架构 |
|---|---|---|
| 部署粒度 | 整体部署(一个WAR包) | 独立部署(每个服务独立容器) |
| 通信方式 | 进程内部调用(或RPC) | 远程调用(HTTP/gRPC/消息队列) |
| 数据存储 | 共享数据库 | 数据库独立(Database per Service) |
| 适用规模 | 中型企业系统 | 大型互联网系统 |
| ERP适用性 | ERP核心模块(财务/生产)适合分层架构 | 非核心外围模块(消息通知/报表)适合微服务 |
🔗 易混淆对照:层次架构属于调用返回风格,不要与数据流风格(管道-过滤器)混淆。ERP场景中不同模块可叠加不同风格,称为混合架构风格(Day 6专题)。
🔗 质量属性场景(6元素)与本案例映射:
场景:可修改性场景 刺激源:业务分析师 刺激:提出新增采购审批加签规则 环境:系统运行中,生产环境 制品:业务逻辑层-审批服务模块 响应:修改审批服务代码,通过接口扩展实现 响应度量:2人天内完成开发,不涉及其他层修改🔗 相关答题模板参考:
- 模板一(架构风格选择)→ 用于Q1的选型理由
- 模板四(方案评价)→ 用于Q4的混合架构分析
🔗 公式速查:
- 层间调用的延迟公式:T_total = Σ(T_serialize + T_network + T_deserialize + T_business)
- 严格分层性能劣化比:Overhead = (n-1) * (DTO拷贝时间 + 参数校验时间),其中n为层数
六、今日金句
“层次架构的核心价值在于关注点分离——每一层只解决一个层面的问题,层间通过稳定的接口契约通信,使系统的可修改性得到质的提升,但代价是调用链路延长带来的性能损耗——这就是架构设计中永恒的权衡:可修改性与性能的跷跷板。”