Day32-01|13.1 层次式体系结构概述:用职责分离控制复杂系统
Day32-01|13.1 层次式体系结构概述:用职责分离控制复杂系统
对应教材:《系统架构设计师教程(第2版)》第13章“层次式架构设计理论与实践”13.1“层次式体系结构概述”。本篇面向软考高级系统架构设计师,重点学习层次式架构的基本思想、层次划分、依赖控制、质量属性、适用场景与案例答题方法。
一、教材定位与学习目标
层次式体系结构是软件架构中最常见、最容易被误解的一类架构。很多系统都有“表示层、业务层、数据访问层”这样的分层,但分层并不只是把代码放进几个目录,也不是层数越多越先进。真正的层次式架构要通过职责分离和依赖约束控制系统复杂度,让每个层次拥有相对明确的职责,让变化能够局部化,让团队能够分工,让质量属性能够被分析和验证。
在高级系统架构设计师考试中,层次式架构经常与信息系统、企业应用、数据访问、物联网和案例分析结合出现。题目可能要求说明层次式架构的优点和缺点,分析某系统的分层是否合理,设计表现层、中间层和数据访问层,或者针对性能、可维护性、扩展性和安全性提出改进。论文题也常把“分层架构设计与实践”作为背景,要求考生说明需求、架构决策、实施过程和最终效果。
今天的学习目标是:
- 理解层次式体系结构的概念、核心思想和基本约束。
- 掌握按职责、抽象程度和变化原因划分层次的方法。
- 区分严格分层、松散分层和可穿透分层的依赖特点。
- 分析层次式架构对可维护性、复用性、性能、安全和团队协作的影响。
- 能够从现状问题出发设计分层方案,并回答案例题和论文题。
二、什么是层次式体系结构
层次式体系结构将系统组织为若干具有明确职责的层次。每一层为其上层提供服务,同时使用其下层提供的服务;上层通常不直接依赖更低层的内部实现。层次之间通过接口、数据契约或抽象模型协作,从而降低模块之间的直接耦合。
用一个典型企业应用举例:
| 层次 | 主要职责 | 不应该承担的职责 |
|---|---|---|
| 表现层 | 接收请求、输入校验、页面或接口响应、交互状态 | 核心业务规则、直接拼接SQL |
| 业务逻辑层 | 用例编排、业务规则、事务边界、领域协作 | 页面布局、数据库连接细节 |
| 数据访问层 | 持久化、查询、映射、连接管理 | 决定业务流程和用户权限 |
| 数据存储层 | 保存数据、索引、备份、恢复 | 直接承载复杂业务规则 |
层次的关键不在于名称,而在于职责和依赖。某些系统还会增加领域层、应用服务层、基础设施层、集成层、公共服务层和设备接入层。无论如何扩展,都需要回答:新增层解决了什么问题,谁依赖谁,跨层调用如何控制,层间模型如何转换。
三、层次式架构的核心思想
1. 关注点分离
将界面交互、业务规则、数据持久化、外部集成和基础设施等不同关注点分开,避免一个模块同时承担多个变化原因。表现层变化时,不应迫使核心业务规则重写;数据库替换时,不应影响用户界面;外部支付接口变化时,不应把第三方协议扩散到整个系统。
关注点分离并不意味着任何两个关注点都必须完全隔离。系统仍然需要协作,关键是通过明确的抽象、接口和转换边界协作。分离的目标是控制变化传播,而不是消灭所有依赖。
2. 抽象逐层提高
通常越靠近上层,越接近用户场景和业务用例;越靠近下层,越接近技术实现和基础设施。上层描述“做什么”,下层描述“如何实现”。例如,业务层可以表达“提交订单”,数据访问层则负责保存订单记录。上层不应依赖某个具体数据库驱动,否则抽象边界就被破坏。
3. 单向依赖
经典层次架构要求依赖方向从上到下,避免下层反向调用上层。单向依赖有利于理解、测试和替换。若数据访问层直接依赖页面控制器,或基础设施层直接决定业务流程,系统就会产生循环依赖和职责倒置。
需要注意,单向依赖不一定意味着所有实现都严格位于同一条垂直链路上。通过依赖倒置和接口抽象,可以让业务层定义抽象接口,由基础设施层提供实现;逻辑上的依赖方向仍然由业务规则主导,而不是被具体技术绑架。
4. 局部化变化
层次划分的价值之一是将变化限制在合理范围。UI框架升级主要影响表现层,数据库驱动升级主要影响基础设施或数据访问层,业务规则变化主要影响业务层。若一个变化需要修改所有层,说明边界、模型或契约设计可能存在问题。
5. 可替换和可测试
层次之间通过契约协作,可以使用模拟对象、测试替身或适配器替换真实依赖。业务层可以在没有真实数据库和外部支付系统的情况下进行单元测试;表现层可以使用模拟应用服务进行接口测试。可测试性不是分层的自动结果,还需要控制全局状态、隐藏实现细节和明确事务边界。
四、如何划分层次
1. 按职责划分
最常见的方法是按照系统职责划分:交互、应用编排、领域规则、数据访问、基础设施和外部集成。职责应尽量具有清晰边界,能够说明输入、输出和服务对象。不要仅按照技术框架名称划分,例如“Spring层”“工具层”“实体层”并不能自动形成合理架构。
2. 按变化原因划分
如果两类功能受到不同因素影响,通常可以考虑分开。例如页面展示会受终端和交互体验影响,业务规则会受政策和经营策略影响,数据存储会受性能和成本影响,外部接口会受供应商协议影响。把变化原因不同的内容放在同一层,会提高修改的连锁影响。
3. 按抽象程度划分
核心业务规则通常应处于较高抽象层,数据库、消息中间件、文件系统和外部SDK处于较低抽象层。抽象程度不是越高越好。过度抽象会增加理解成本和运行开销,甚至让简单业务变得复杂。架构师要根据系统寿命、变化概率和复用价值确定抽象边界。
4. 按部署边界划分
有时层次也与部署单元相关,例如前端节点、应用节点、服务节点、数据节点和设备接入节点。但逻辑层次与物理部署不能完全等同。逻辑上属于同一层的组件可以部署在不同节点,逻辑上不同层的组件也可能暂时部署在同一进程中。先设计职责和依赖,再决定部署方式。
5. 控制层次数量
层次太少,职责容易混杂;层次太多,调用链变长,理解和调试困难。层次数量应由业务复杂度、团队规模、系统生命周期、质量属性和复用需求决定。一个小型内部工具使用三层可能已经足够;一个大型企业平台可能需要更细的表现、应用、领域、集成、数据和基础设施边界。
五、严格分层、松散分层与可穿透分层
1. 严格分层
严格分层要求第N层只能调用第N-1层,不能越过中间层调用更低层。它的优点是依赖关系清晰、边界容易治理、替换和测试较为稳定;缺点是简单请求也可能穿过多个层次,增加代码量、调用次数和延迟。严格分层适合职责明确、治理要求高、系统生命周期长的场景。
2. 松散分层
松散分层允许某些上层在明确规则下调用更低层,以减少不必要的转发。例如只读查询可以通过专用查询模型直接访问数据服务,避免复杂的业务对象转换。松散分层灵活性更高,但需要严格约束哪些场景可以越层、由谁审批、如何监控,否则容易逐渐退化为任意依赖。
3. 可穿透分层
可穿透分层允许请求穿过某些层次,但不应被理解为“任何模块都可以访问任何模块”。它通常用于性能敏感的查询、基础设施能力复用或渐进式遗留系统改造。使用时必须记录原因、影响、替代方案和退出条件,并通过接口和访问控制限制穿透范围。
| 类型 | 依赖规则 | 优点 | 风险 |
|---|---|---|---|
| 严格分层 | 只能调用直接相邻层 | 清晰、易治理 | 延迟和转发开销 |
| 松散分层 | 允许受控越层 | 灵活、性能较好 | 规则失控后耦合扩大 |
| 可穿透分层 | 特定场景可跨层 | 适合查询和迁移 | 边界容易被破坏 |
考试答题时,不要简单说某一种永远最好。应结合系统场景、质量属性和治理能力说明选择依据。
六、层次式架构对质量属性的影响
1. 可维护性
职责分离、低耦合和统一契约有助于定位问题和实施变更。维护人员可以根据故障位置缩小排查范围。但层次划分不合理会导致业务逻辑散落、对象在层间反复转换,反而增加维护负担。因此要保持业务规则集中、接口语义稳定和跨层转换可追踪。
2. 可复用性
业务服务和公共能力可以被多个表现层或渠道复用。统一的应用服务支持Web、移动端和内部接口,数据访问组件可以复用连接管理和查询能力。复用必须建立在稳定的业务语义上,不能为了复用而抽出过于通用、难以理解的“万能服务”。
3. 性能
每增加一层,可能增加对象转换、序列化、网络调用和事务协调开销。性能优化时应先识别瓶颈,再决定是否缓存、批量化、异步化或采用专用查询模型,而不是随意绕过层次。越层访问要有明确的性能收益和治理边界。
4. 安全性
层次可以形成安全边界。表现层负责输入校验和会话控制,应用层负责授权和用例权限,数据访问层负责参数化查询和数据过滤,基础设施层负责网络隔离和密钥管理。安全不能只放在表现层,否则内部调用和批处理入口可能绕过控制。
5. 可扩展性
稳定的业务接口和可替换的技术实现有利于增加新渠道、数据库或外部伙伴。扩展设计还要考虑版本兼容、幂等、限流、配置管理和运行监控。只增加代码入口而没有统一契约,不能称为真正的可扩展。
6. 可部署性与可运维性
逻辑层次为部署拆分提供依据,但不必强制每层独立部署。独立部署可以提高扩展和隔离能力,也会增加网络、发布、监控和故障处理成本。应按照变化频率、资源特征、可靠性和团队边界决定部署单元。
七、层间协作与模型转换
层次式架构经常需要处理不同模型之间的转换。表现层模型关注输入输出和展示;应用层模型关注用例参数;领域模型关注业务规则和不变量;持久化模型关注表结构和索引;外部接口模型关注第三方协议。把所有层强行使用同一个对象,虽然短期代码少,但会让一个模型承载多个变化原因。
转换也不能无条件增加。简单查询场景可以使用轻量数据传输对象;复杂核心领域应保护领域模型,避免数据库字段直接泄露到业务和页面。转换规则要明确字段来源、缺省值、校验、敏感字段和版本兼容,必要时保留映射测试。
事务边界通常由业务用例决定,而不是由数据库访问方法决定。应用层应负责启动和结束用例事务,领域层负责业务不变量,数据访问层负责持久化操作。跨多个资源的事务要根据一致性要求选择本地事务、消息最终一致性、补偿或对账,不应把所有问题都交给数据库事务。
八、案例分析:企业采购系统的层次式架构
某企业采购系统原来由一个大型Web应用构成,页面控制器直接访问数据库,采购规则、审批逻辑和消息通知散落在多个页面中。系统存在重复代码、权限绕过、数据库升级困难和移动端无法复用等问题。企业计划支持移动采购、供应商门户和自动化审批。
1. 问题分析
第一,表现和业务逻辑耦合,页面变化会影响审批规则。第二,数据库结构直接暴露,导致业务代码依赖表字段。第三,不同入口重复实现权限和采购校验。第四,通知、审批和采购单状态没有统一模型。第五,所有功能部署在一个应用中,局部高峰会影响整个系统。
2. 目标分层
表现层为Web、移动端和供应商门户提供不同适配,统一调用应用服务;应用层负责创建采购申请、提交审批、确认收货等用例编排;领域层集中采购规则、额度控制、审批状态和供应商约束;集成层负责消息、企业通讯录、财务和供应商系统适配;数据访问层隐藏数据库和ORM细节;基础设施层提供缓存、日志、认证、文件和消息能力。
3. 关键决策
采购申请提交采用统一应用服务,所有入口使用同一授权和校验链路。审批状态使用状态机管理,状态变更发布领域事件,由通知和财务适配器异步处理。核心采购数据仍保留在原数据库,但通过数据访问层隔离表结构。对于报表查询,采用专用查询模型,避免复杂统计影响事务链路。服务和事件都定义版本、幂等和审计规则。
4. 迁移方案
先抽取公共授权、采购规则和状态模型,在原应用中以模块方式运行;再将移动端接入应用服务;随后通过适配器接入供应商门户和财务系统;最后根据运行数据拆分高负载查询和异步通知组件。每次迁移都进行双轨校验、回退准备和指标观察,避免一次性重构造成业务中断。
5. 效果指标
可用新增渠道接入周期、采购规则重复率、权限缺陷数、审批处理时长、系统峰值响应时间、通知延迟、数据库变更影响范围和故障平均恢复时间评价效果。架构改善必须通过可观测指标验证。
九、综合知识练习与详细答案
练习一:单项选择
层次式体系结构最核心的设计目标是( )。
A. 增加系统层数 B. 让每一层都能直接访问数据库 C. 通过职责分离和依赖控制降低复杂度 D. 让所有组件部署在不同服务器
答案:C。层次的价值在于职责分离、抽象和依赖控制。层数、数据库访问方式和部署数量都不是架构目标本身。
练习二:多项选择
合理的层次式架构通常具有( )特征。
A. 层次职责清晰 B. 依赖方向可控 C. 业务规则集中 D. 所有层共享同一数据库对象 E. 可通过契约进行测试
答案:A、B、C、E。所有层共享同一数据库对象会使数据结构变化扩散到整个系统,破坏层间隔离。
练习三:案例题
某系统规定所有请求必须依次经过表现层、业务层、数据访问层,但一个高频只读报表因此响应缓慢。开发人员准备让报表页面直接查询数据库。请分析该方案的风险,并给出更合理的解决方案。
参考答案:直接查询数据库会绕过权限、审计、数据脱敏和连接管理,导致页面依赖表结构;还可能与核心事务竞争资源,数据库变化会影响报表。可以先通过性能分析确认瓶颈,再采用专用查询服务或查询模型,将报表所需字段和权限封装在稳定接口中;使用只读副本、缓存、预聚合、异步生成或批量计算降低压力;对报表访问保留统一认证、授权、审计和数据过滤。若确需受控越层,应限定在只读、专用账号、专用视图或查询服务范围内,记录架构例外和退出条件,并通过性能、权限和数据一致性测试验证。
十、论文写作素材
开头模板
“随着企业采购业务扩展到移动端、供应商门户和自动化审批,原有页面、业务规则和数据库高度耦合的系统已经难以支撑变化。为提高可维护性、复用性和扩展性,我参与了层次式架构改造,按照关注点分离原则重新划分表现层、应用层、领域层、集成层、数据访问层和基础设施层,并通过渐进式迁移降低改造风险。”
正文可写的论点
第一,说明如何根据职责和变化原因划分层次,避免按目录或技术框架机械分层;第二,说明如何通过接口、模型转换、事务边界和依赖倒置保护业务规则;第三,说明严格分层与受控越层的权衡,以及如何用查询模型、缓存、异步和只读副本解决性能问题;第四,说明安全、日志、监控、版本和测试如何贯穿各层。
结尾模板
“层次式架构的价值不在于层数多少,而在于是否建立了清晰的职责边界、稳定的协作契约和可控的依赖方向。实践中应避免教条式分层,根据业务复杂度和质量属性进行权衡,并通过指标持续验证架构是否真正降低了变化成本。”
十一、今日复盘
本节可以用一句话总结:层次式体系结构通过把不同变化原因隔离在不同职责边界内,减少复杂系统中的变化传播。
请回答以下问题:
- 层次式架构与简单的代码目录划分有什么区别?
- 为什么表现层不应直接拼接SQL并决定核心业务规则?
- 严格分层和松散分层分别适合什么场景?
- 如何处理层次增加带来的性能损耗?
- 为什么逻辑分层不等于物理独立部署?
- 如何通过指标判断一次分层改造是否成功?
复盘时请以一个熟悉的企业系统为例,画出至少四个逻辑层次,标注每层职责、允许的依赖方向、关键接口和主要质量属性。若能够进一步写出一个分层改造案例的现状问题、架构决策、迁移步骤和验证指标,就具备了本节在综合知识、案例分析和论文写作中的完整答题能力。