分层架构的核心价值是"封装外部交互"——通过将系统与外部世界的交互封装到不同层次,让业务逻辑层专注于领域本身的逻辑,从而实现关注点分离、降低系统复杂度。正如温昱在《一线架构师实践指南》中所说:"在架构设计初期100%的系统都可以用分层架构,就算随着设计的深入而采用了其他架构模式也未必和分层架构矛盾。"本文通过分层架构的核心思想和从上下文图到架构设计的实践方法两个核心维度,帮你掌握"知其所以然"的分层架构设计方法。
核心知识点:连续论证"是什么-为什么-怎么选"
知识点1:分层架构的"封装外部交互"思想——从业务痛点到架构方案
通俗理解:分层架构就像一家餐厅的组织结构——服务员负责接待顾客(UI层),厨师负责做菜(业务逻辑层),仓库管理员负责管理食材(数据层),采购员负责与供应商打交道(系统交互层)。每个角色只负责自己的事,互不干扰,这样餐厅才能高效运转。
核心作用:分层架构通过 “封装外部交互”,(todo:架构思维的一种)将系统与外部世界的各种交互方式(用户交互、数据库访问、外部系统通信、硬件控制)封装到不同层次,让业务逻辑层专注于业务本身,从而实现关注点分离、降低系统复杂度、提高可维护性。
深入论证:为什么需要封装外部交互?这背后解决的是什么业务问题?
业务痛点1:业务逻辑与技术细节耦合,导致维护成本高
想象一个电商系统:当用户下单时,业务逻辑需要处理"如何连接MySQL数据库" “如何调用支付接口”"如何发送短信通知"等技术细节。如果这些细节直接写在业务代码里,会出现什么问题?
- 问题1:技术变更影响业务:如果支付接口从支付宝换成微信支付,需要修改业务代码;如果数据库从MySQL换成PostgreSQL,需要修改业务代码。每次技术变更都要改业务逻辑,风险高、成本大。
- 问题2:业务逻辑难以理解:业务代码里混杂着数据库连接、HTTP请求、消息队列等技术细节,业务逻辑被技术细节淹没,新人难以理解"下单"这个业务到底是怎么实现的。
- 问题3:重复代码多:多个业务功能都需要访问数据库、调用外部接口,如果每个功能都自己实现,会导致大量重复代码,维护困难。
(todo:架构方案)解决方案:封装外部交互,让业务逻辑与技术细节分离
分层架构的核心思想是:为每种外部交互方式设计一个封装层,业务逻辑层只调用封装层提供的接口,不需要知道具体实现。这就像餐厅的厨师,不需要知道食材是从哪个供应商采购的,只需要告诉采购员"我需要什么食材",采购员负责具体的采购工作。
这样设计解决了什么业务问题?
- 降低维护成本:当支付接口升级时,只需要修改封装层,业务逻辑层不需要改动。这避免了"牵一发而动全身"的问题,降低了维护成本。
- 提高代码可读性:业务逻辑层只包含业务逻辑,不包含技术细节,代码更清晰,新人更容易理解。
- 支持代码复用:封装好的交互层可以在多个业务场景中复用,避免重复实现。例如,数据访问层封装了数据库操作,订单模块、商品模块、用户模块都可以使用。
分层架构的"封装外部交互"思想:
决策逻辑:什么时候需要分层架构?什么时候不需要?
- 需要分层架构的场景:系统需要与多种外部实体交互(用户、数据库、外部系统、硬件),且交互方式可能变化或需要复用。例如,电商系统需要与用户交互、访问数据库、调用支付接口,这些交互方式可能变化(支付接口升级、数据库迁移),需要封装。
- 不需要分层架构的场景:系统是纯计算系统,不涉及外部交互(如数学计算库、算法库),此时分层架构的价值有限。例如,一个计算斐波那契数列的库,不需要与外部交互,直接实现算法即可,不需要分层。
要点2:四层架构模式——如何设计封装层?
通俗理解:四层架构就像餐厅的四个部门——服务员部门(UI层)负责接待顾客,厨师部门(PD层)负责做菜,仓库部门(DM层)负责管理食材,采购部门(SI层)负责与供应商打交道。每个部门只负责自己的事,互不干扰。
核心作用:四层架构模式是分层架构的经典模式,通过识别系统需要与哪些外部实体交互,确定需要哪些封装层。这四层分别是:UI层(用户界面层)、SI层(系统交互层)、PD层(问题领域层)、DM层(数据管理层)。
四层架构示意图:
深入论证:为什么需要这四层?每层解决什么业务问题?
UI层(用户界面层)——解决"用户交互方式变化"的业务问题
业务场景:电商系统需要支持Web界面、移动App、小程序等多种用户交互方式。如果业务逻辑直接处理这些交互方式,会出现什么问题?
- 问题:每种交互方式的技术实现不同(Web用HTML/CSS/JavaScript,移动App用原生开发或React Native),如果业务逻辑直接处理,会导致业务逻辑与交互方式耦合。当需要增加新的交互方式(如语音助手)时,需要修改业务逻辑,风险高。
- 解决方案:UI层封装所有用户交互方式,为业务层提供统一的接口。无论用户通过什么方式与系统交互,业务层都调用同一个接口。这就像餐厅的服务员,无论顾客是打电话订餐、到店点餐还是通过App下单,服务员都提供统一的服务接口。
- 业务价值:当需要增加新的交互方式时,只需要增加新的UI层实现,业务逻辑层不需要改动。这降低了系统复杂度,提高了可扩展性。
SI层(系统交互层)——解决"外部系统集成复杂"的业务问题
业务场景:电商系统需要与支付系统、物流系统、短信系统等多个外部系统集成。如果业务逻辑直接处理这些集成,会出现什么问题?
- 问题:每个外部系统的接口协议不同(有的用HTTP,有的用消息队列,有的用专用协议),如果业务逻辑直接处理,会导致业务逻辑与外部系统耦合。当外部系统接口升级或更换供应商时,需要修改业务逻辑,风险高。
- 解决方案:SI层封装所有外部系统交互,为业务层提供统一的接口。无论外部系统使用什么协议,业务层都调用同一个接口。这就像翻译官,无论外部系统使用什么协议、什么语言,翻译官都提供统一的接口。
- 业务价值:当外部系统接口升级或更换供应商时,只需要修改SI层,业务逻辑层不需要改动。这降低了系统复杂度,提高了可维护性。
PD层(问题领域层)——系统的核心,专注于业务逻辑
业务场景:电商系统的核心是"下单"这个业务逻辑——检查库存、计算价格、创建订单、扣减库存、调用支付。如果这些业务逻辑与技术细节混在一起,会出现什么问题?
- 问题:业务逻辑与技术细节混在一起,导致业务逻辑难以理解、难以测试、难以维护。新人难以理解"下单"这个业务到底是怎么实现的。
- 解决方案:PD层只包含业务逻辑,不包含技术细节。PD层通过调用UI层、SI层、DM层提供的接口,实现业务逻辑。这就像厨师,不需要知道如何接电话、如何收银,只需要专注于做菜。
- 业务价值:业务逻辑清晰、易于理解、易于测试、易于维护。这提高了开发效率,降低了维护成本。
DM层(数据管理层)——解决"数据存储方式变化"的业务问题
业务场景:系统可能需要使用MySQL、PostgreSQL、MongoDB等多种数据库,也可能需要使用文件系统、Redis等存储方式。如果业务逻辑直接处理这些存储方式,会出现什么问题?
- 问题:每种存储方式的操作方式不同(关系数据库用SQL,NoSQL用API,文件系统用文件操作),如果业务逻辑直接处理,会导致业务逻辑与存储方式耦合。当需要更换存储方式时,需要修改业务逻辑,风险高。
- 解决方案:DM层封装所有数据存储方式,为业务层提供统一的接口。无论使用什么存储方式,业务层都调用同一个接口。这就像仓库管理员,无论货物存在哪个仓库、用什么方式存储,管理员都提供统一的存取接口。
- 业务价值:当需要更换存储方式时,只需要修改DM层,业务逻辑层不需要改动。这降低了系统复杂度,提高了可扩展性。
决策逻辑:什么时候需要哪一层?
- 需要UI层:系统需要与用户交互(如Web应用、桌面应用)。如果系统没有用户界面(如后台服务、嵌入式控制程序),则不需要UI层。
- 需要SI层:系统需要与外部系统交互或控制硬件设备(如EAI系统、网管系统、嵌入式系统)。如果系统不涉及外部系统或硬件,则不需要SI层。
- 需要PD层:所有系统都需要PD层,因为业务逻辑是系统的核心。
- 需要DM层:系统需要持久化数据(如使用数据库、文件系统)。如果系统不涉及数据持久化(如纯计算系统),则不需要DM层。
要点3:三层架构是四层架构的具体应用
本质原理:常见的"展现层+业务层+数据层"三层架构,实际上是四层架构模式的一种简化应用——忽略了系统交互层,或者将系统交互层的职责合并到其他层。
三层架构示意图:
三层架构与四层架构的关系:
为什么这样设计:
- 三层架构的简化:对于大多数业务应用系统(如企业管理系统、电商系统),主要涉及用户交互和数据库访问,不涉及外部系统交互或硬件控制,因此可以忽略SI层,简化为三层架构。这就像盖房子,如果不需要车库,就不需要设计车库,但设计思路(房间布局)是一样的。
- 业务实体层的提炼:三层架构中,有时会单独提炼出"业务实体层"(如HotelManagerModels),用于定义业务领域的概念和数据结构。这实际上是将PD层中的"领域模型"部分单独提炼出来,便于复用和维护。这就像图书馆的目录系统,将书籍信息单独管理,便于查找和复用。
决策逻辑:
- 用三层架构:系统主要涉及用户交互和数据库访问,不涉及外部系统或硬件控制(如企业管理系统、电商系统)。
- 用四层架构:系统涉及外部系统交互或硬件控制(如EAI系统、网管系统、嵌入式系统),需要专门的SI层来封装这些交互。
知识点2:从上下文图到分层架构的设计方法
分层架构设计不是凭空想象,而是从需求出发,通过上下文图识别外部实体,然后设计对应的封装层。这是分层架构设计的核心实践方法。
要点1:为什么从上下文图开始?
本质原理:上下文图是需求分析的工具,用于描述"系统与外部世界的关系"。分层架构的核心是"封装外部交互",因此需要先识别"系统需要与哪些外部实体交互",然后为每种外部实体设计对应的封装层。
为什么这样设计:
- 需求驱动设计:分层架构设计应该从需求出发,而不是从技术出发。上下文图清晰地描述了系统需要与哪些外部实体交互,这直接决定了需要哪些封装层。这就像盖房子,先确定需要哪些房间(需求),再设计房间布局(架构),而不是先设计布局再想需要什么房间。
- 避免过度设计:如果系统不需要与外部系统交互,就不需要设计SI层;如果系统不需要持久化数据,就不需要设计DM层。通过上下文图识别外部实体,可以避免设计不必要的层,降低系统复杂度。
- 确保完整性:上下文图帮助系统化地识别所有外部实体,避免遗漏。例如,系统可能需要与用户、数据库、外部系统、硬件设备、定时任务等多种外部实体交互,通过上下文图可以确保不遗漏。
决策逻辑:
- 必须用上下文图:设计分层架构时,必须先用上下文图识别外部实体,然后根据外部实体设计对应的封装层。
- 上下文图的画法:可以使用顶层数据流图、用例图(将System处理成黑盒)、PowerPoint框图等方式绘制,关键是识别外部实体。
要点2:识别4种外部实体
本质原理:系统需要与4种外部实体交互,每种外部实体对应一种封装层。
为什么这样设计:
- 外部用户:系统需要与用户交互(终端用户、管理员),对应UI层。用户通过界面与系统交互,UI层封装这些交互方式(Web界面、移动App、命令行等),为业务层提供统一接口。
- 持久化存储设施:系统需要持久化数据(关系数据库、文件系统、Flash存储等),对应DM层。DM层封装这些存储方式的具体操作(SQL查询、文件读写等),为业务层提供统一的数据访问接口。
- 外部系统与底层硬件:系统可能需要与外部系统交互(如银行系统、第三方支付系统),或控制硬件设备(如网管系统管理网络设备),对应SI层。SI层封装这些交互方式(HTTP接口、专用协议、硬件驱动等),为业务层提供统一接口。
- 时限触发机制:系统可能需要定时执行任务(如定时报表、定时数据同步),这可以视为一种"外部触发"。时限触发机制可能属于SI层(如果涉及外部系统交互),也可能属于PD层(如果是系统内部的定时任务)。
决策逻辑:
- 识别外部用户:系统是否有用户界面?如果有,需要UI层。
- 识别持久化存储:系统是否需要持久化数据?如果需要,需要DM层。
- 识别外部系统与硬件:系统是否需要与外部系统交互或控制硬件?如果需要,需要SI层。
- 识别时限触发:系统是否有定时任务?如果有,需要确定属于哪一层。
要点3:根据外部实体设计分层架构
本质原理:识别外部实体后,为每种外部实体设计对应的封装层,然后设计业务逻辑层(PD层),形成完整的分层架构。
外部实体启发分层架构设计:
为什么这样设计:
- 一一对应关系:外部用户→UI层,外部系统/硬件→SI层,持久化存储→DM层,业务逻辑→PD层。这种一一对应关系使得分层架构设计变得简单直接,不需要猜测需要哪些层。
- 职责清晰:每个层只负责封装一种外部交互,职责清晰,便于维护。例如,UI层只负责用户交互,不涉及数据库操作;DM层只负责数据访问,不涉及业务逻辑。
- 易于扩展:如果系统需要增加新的外部交互方式(如增加消息队列、增加新的外部系统),只需要增加对应的封装层或扩展现有层,不影响其他层。
决策逻辑:
- 设计UI层:如果识别到外部用户,设计UI层,确定UI层的职责(管理员界面、业务用户界面、报表功能界面等)。
- 设计SI层:如果识别到外部系统或硬件,设计SI层,确定SI层的职责(与哪些外部系统交互、采用什么协议、使用什么SDK等)。
- 设计DM层:如果识别到持久化存储,设计DM层,确定DM层的职责(使用什么数据库、如何访问文件、如何操作Flash等)。
- 设计PD层:所有系统都需要PD层,PD层是系统的核心,负责实现业务逻辑。
知识点3:分层架构的优势与局限
分层架构不是万能的,理解其优势和局限,是正确使用分层架构的关键。
要点1:分层架构的核心优势
本质原理:分层架构通过"封装外部交互"和"关注点分离",实现了系统结构的清晰化和可维护性的提升。
为什么这样设计:
- 关注点分离:每个层只负责一种关注点(用户交互、业务逻辑、数据访问等),不同层的代码互不干扰,便于理解和维护。这就像公司的部门划分,每个部门负责一个领域,职责清晰。
- 标准化调用关系:分层架构定义了标准的调用关系(上层调用下层,不能跨层调用),减少了层之间的依赖,降低了系统复杂度。这就像公司的汇报关系,员工只能向直接上级汇报,不能越级汇报。
- 易于替换实现:如果层间接口设计合理,替换某一层的实现(如将MySQL换成PostgreSQL,或将Web界面换成移动App)不会影响其他层。这就像更换手机外壳,不影响手机内部功能。
决策逻辑:
- 适合用分层架构:系统需要与多种外部实体交互,且交互方式可能变化;系统需要支持多人协作开发,需要清晰的职责划分。
- 不适合用分层架构:系统非常简单,只有单一功能,不需要分层;系统是纯计算系统,不涉及外部交互。
要点2:分层架构的局限性
本质原理:分层架构通过"封装"实现了关注点分离,但也可能带来性能开销和开发复杂度。
为什么这样设计:
- 性能开销:分层架构增加了调用层次,每次调用都需要经过多个层,可能带来性能开销。例如,用户请求需要经过UI层→业务层→数据层,每层都有处理时间。这就像快递配送,经过多个中转站,虽然流程清晰,但可能增加配送时间。
- 开发复杂度:分层架构需要定义层间接口,需要管理层间依赖,增加了开发复杂度。例如,需要定义Service接口、DAO接口,需要管理依赖注入等。这就像盖房子,虽然房间划分清晰,但需要设计房间之间的通道和门。
决策逻辑:
- 接受性能开销:如果系统的可维护性和可扩展性比性能更重要(如企业管理系统),可以接受分层架构带来的性能开销。
- 优化性能:如果系统对性能要求极高(如高频交易系统),可以在分层架构的基础上进行性能优化(如减少调用层次、使用缓存等)。
要点3:分层架构与细粒度模块划分
本质原理:分层架构解决了"如何分层"的问题,但没有解决"层内如何划分模块"的问题。细粒度模块划分需要在层内进行。
为什么这样设计:
- 分层是粗粒度划分:分层架构将系统划分为几个大层(UI层、业务层、数据层等),这是粗粒度的划分。每个层内部可能包含多个模块(如业务层包含用户模块、订单模块、支付模块等),这些模块的划分需要在层内进行。
- 层内模块划分更容易:一旦确定了分层架构,层内的模块划分就变得相对容易,因为每个层的职责已经明确。例如,业务层的职责是实现业务逻辑,那么业务层的模块划分就是按照业务功能划分(用户管理、订单管理、支付管理等)。
决策逻辑:
- 先分层,再分模块:先设计分层架构(确定有哪些层),再在层内进行模块划分(确定每层有哪些模块)。
- 模块划分原则:按照业务功能划分模块(如用户模块、订单模块),每个模块负责一个业务领域。
实战场景串联
场景1:从业务痛点到分层架构设计的完整流程
业务背景:某公司需要开发网络管理系统,用于管理公司内部的网络设备(交换机、路由器等),提供Web管理界面供管理员使用,存储设备配置信息到数据库,与外部监控系统集成,实现设备状态监控和告警管理。
业务痛点识别:
痛点1:系统需要与多种外部实体交互,技术细节复杂
- 需要与管理员交互(Web界面)
- 需要管理网络设备(通过SNMP协议)
- 需要与外部监控系统集成(通过HTTP接口)
- 需要存储数据到数据库(MySQL)
- 如果业务逻辑直接处理这些交互,会导致业务逻辑与技术细节耦合,难以维护。
痛点2:外部系统接口可能变化,需要支持灵活扩展
- 网络设备可能更换(从Cisco换成华为),SNMP协议实现可能不同
- 外部监控系统可能升级,HTTP接口可能变化
- 数据库可能迁移(从MySQL换成PostgreSQL)
- 如果业务逻辑直接处理这些变化,会导致大量修改,风险高。
痛点3:需要支持多人协作开发,需要清晰的职责划分
- 前端开发人员负责Web界面
- 后端开发人员负责业务逻辑
- 数据库开发人员负责数据访问
- 如果职责不清晰,会导致代码混乱,影响开发效率。
技术挑战:如何设计合理的分层架构?需要哪些层?每层的职责是什么?如果分层不合理,会导致代码混乱、难以维护,影响系统质量和开发效率。
解决方案:用分层架构解决业务痛点
第一步:识别业务痛点对应的外部实体
核心思路:分层架构的核心是"封装外部交互",因此需要先识别"系统需要与哪些外部实体交互",然后为每种外部实体设计对应的封装层。这就像盖房子,先确定需要哪些房间(需求),再设计房间布局(架构)。
识别4种外部实体:
外部实体1:外部用户——对应业务痛点"需要与管理员交互"
- 识别结果:网络管理员(通过Web界面管理系统)
- 业务价值:系统需要提供Web管理界面,管理员通过界面管理系统,这是系统的核心用户交互方式。如果不识别,会导致无法设计UI层,业务逻辑需要直接处理Web请求,增加复杂度。
外部实体2:持久化存储设施——对应业务痛点"需要存储数据"
- 识别结果:MySQL数据库(存储设备配置信息、告警信息等)
- 业务价值:系统需要存储设备配置、告警信息等数据,需要使用数据库。如果不识别,会导致无法设计DM层,业务逻辑需要直接处理数据库操作,增加复杂度。
外部实体3:外部系统与底层硬件——对应业务痛点"需要管理设备和集成外部系统"
- 识别结果:
- 被管理的网络设备(交换机、路由器等,通过SNMP协议管理)
- 外部监控系统(通过HTTP接口集成)
- 业务价值:系统需要管理网络设备(这是硬件设备),需要与外部监控系统集成(这是外部系统)。如果不识别,会导致无法设计SI层,业务逻辑需要直接处理SNMP协议和HTTP接口,增加复杂度。
外部实体4:时限触发机制——对应业务痛点"需要定时执行任务"
- 识别结果:定时任务(如定时采集设备状态、定时生成报表)
- 业务价值:系统需要定时执行任务(如定时采集设备状态),这是系统的重要功能。如果不识别,会导致定时任务的处理逻辑不清晰,可能混在业务逻辑中,增加复杂度。
上下文图示例(用文字描述):
系统外部实体:
- 网络管理员(用户)
- MySQL数据库(持久化存储)
- 网络设备(硬件,通过SNMP协议)
- 外部监控系统(外部系统,通过HTTP接口)
- 定时任务(时限触发)
第二步:用核心知识点拆解方案——根据外部实体设计分层架构
核心思路:根据"外部实体→封装层"的一一对应关系,为每种外部实体设计对应的封装层,然后设计业务逻辑层(PD层),形成完整的分层架构。这解决了业务痛点"系统需要与多种外部实体交互,技术细节复杂"。
设计UI层(用户界面层)——解决业务痛点"需要与管理员交互"
设计决策:
- 是否需要UI层:系统有Web管理界面,需要UI层。
- UI层职责:
- 管理员界面:设备管理界面、告警管理界面、报表界面
- Web界面实现:HTML、CSS、JavaScript等前端技术
为什么这样设计:
- 解决业务痛点:UI层封装Web界面的具体实现,为业务层提供统一的接口。当需要增加新的交互方式(如移动App)时,只需要增加新的UI层实现,业务逻辑层不需要改动。这解决了业务痛点"外部系统接口可能变化,需要支持灵活扩展"。
- 业务价值:管理员通过Web界面与系统交互,UI层屏蔽Web界面的技术细节,业务层只需要处理业务逻辑,不需要关心HTML、CSS、JavaScript等前端技术。这降低了系统复杂度,提高了开发效率。
注意事项:如果系统提供RESTful API供外部系统调用,这部分不属于UI层,而是PD层提供的服务的可远程访问的二次封装。如果"对外接口"包含负责与外部系统双向交互的逻辑(如事件队列),则应该划归SI层。
设计SI层(系统交互层)——解决业务痛点"需要管理设备和集成外部系统"
设计决策:
- 是否需要SI层:系统需要管理网络设备(硬件),需要与外部监控系统集成(外部系统),需要SI层。
- SI层职责:
- 封装硬件设备访问:封装SNMP协议,实现与网络设备的交互(采集设备状态、下发配置等)
- 封装外部系统交互:封装HTTP接口,实现与外部监控系统的交互(发送告警信息、接收监控数据等)
为什么这样设计:
- 解决业务痛点:SI层封装SNMP协议和HTTP接口的具体实现,为业务层提供统一的接口。当网络设备更换(从Cisco换成华为)或外部监控系统升级时,只需要修改SI层,业务逻辑层不需要改动。这解决了业务痛点"外部系统接口可能变化,需要支持灵活扩展"。
- 业务价值:业务层不需要知道SNMP协议的具体实现、HTTP接口的具体调用方式,只需要调用SI层提供的接口即可。这降低了系统复杂度,提高了可维护性。当需要增加新的外部系统集成时,只需要在SI层增加新的封装,业务逻辑层不需要改动。
设计DM层(数据管理层)——解决业务痛点"需要存储数据"
设计决策:
- 是否需要DM层:系统需要持久化数据(设备配置、告警信息等),需要DM层。
- DM层职责:
- 封装DB访问:封装MySQL数据库的访问(SQL查询、事务管理等)
为什么这样设计:
- 解决业务痛点:DM层封装MySQL数据库的具体操作,为业务层提供统一的数据访问接口。当数据库迁移(从MySQL换成PostgreSQL)时,只需要修改DM层,业务逻辑层不需要改动。这解决了业务痛点"外部系统接口可能变化,需要支持灵活扩展"。
- 业务价值:业务层不需要知道SQL语句的具体写法、数据库连接的具体管理,只需要调用DM层提供的接口即可。这降低了系统复杂度,提高了可维护性。当需要增加新的数据存储方式(如Redis缓存)时,只需要在DM层增加新的封装,业务逻辑层不需要改动。
设计PD层(问题领域层)——系统的核心,专注于业务逻辑
设计决策:
- 是否需要PD层:所有系统都需要PD层,PD层是系统的核心。
- PD层职责:
- 设备管理:设备信息管理、设备状态监控、设备配置下发
- 告警管理:告警信息处理、告警规则管理
- 报表管理:报表生成、报表查询
为什么这样设计:
- 解决业务痛点:PD层只包含业务逻辑,不包含技术细节。PD层通过调用UI层、SI层、DM层提供的接口,实现业务逻辑。这解决了业务痛点"需要支持多人协作开发,需要清晰的职责划分"——前端开发人员负责UI层,后端开发人员负责PD层,数据库开发人员负责DM层,职责清晰,互不干扰。
- 业务价值:业务逻辑清晰、易于理解、易于测试、易于维护。新人可以快速理解"设备管理"这个业务到底是怎么实现的,不需要关心SNMP协议、HTTP接口、SQL语句等技术细节。这提高了开发效率,降低了维护成本。
分层架构设计结果:
graph TB
subgraph "网络管理系统分层架构"
UI层[UI层<br/>用户界面层]
PD层[PD层<br/>问题领域层]
SI层[SI层<br/>系统交互层]
DM层[DM层<br/>数据管理层]
end
subgraph "UI层职责"
UI1[管理员界面<br/>设备管理、告警管理、报表管理]
UI2[Web界面实现<br/>HTML、CSS、JavaScript]
end
subgraph "PD层职责"
PD1[设备管理模块]
PD2[告警管理模块]
PD3[报表管理模块]
end
subgraph "SI层职责"
SI1[硬件设备访问<br/>SNMP协议封装]
SI2[外部系统交互<br/>HTTP接口封装]
end
subgraph "DM层职责"
DM1[数据库访问<br/>MySQL封装]
end
UI层 --> UI1
UI层 --> UI2
UI层 --> PD层
PD层 --> PD1
PD层 --> PD2
PD层 --> PD3
PD层 --> SI层
PD层 --> DM层
SI层 --> SI1
SI层 --> SI2
DM层 --> DM1
style UI层 fill:#e1f5ff
style PD层 fill:#fff4e1
style DM层 fill:#e8f5e9
style SI层 fill:#fce4ec
第三步:长期适配策略——验证分层架构的合理性
核心思路:验证分层架构是否能够支持系统的长期演进,是否能够解决业务痛点。这包括验证层间调用关系、职责清晰性、可扩展性。
验证1:层间调用关系——确保系统结构清晰
验证标准:UI层→PD层→SI层/DM层,不能跨层调用(如UI层不能直接调用DM层)。
验证结果:分层架构符合标准调用关系,UI层调用PD层,PD层调用SI层和DM层。
业务价值:如果允许跨层调用(如UI层直接调用DM层),会导致层间依赖混乱,增加系统复杂度。标准调用关系(上层调用下层)使得系统结构清晰,便于理解和维护。这解决了业务痛点"需要支持多人协作开发,需要清晰的职责划分"。
验证2:职责清晰性——确保每层职责单一
验证标准:每层职责单一,UI层只负责用户交互,PD层只负责业务逻辑,SI层只负责外部系统/硬件交互,DM层只负责数据访问。
验证结果:每层职责清晰,没有职责重叠。
业务价值:如果某层职责不清晰(如PD层既负责业务逻辑,又负责数据库操作),会导致代码混乱,难以维护。职责清晰使得每层代码独立,便于理解和修改。这解决了业务痛点"需要支持多人协作开发,需要清晰的职责划分"。
验证3:可扩展性——确保系统能够长期演进
验证标准:如果需要增加新功能(如增加设备性能监控),只需要在PD层增加新模块,调用SI层和DM层的接口即可,不需要修改其他层。
验证结果:分层架构支持扩展,新功能可以独立开发,不影响现有功能。
业务价值:系统需要不断演进,增加新功能。如果架构不支持扩展,每次增加新功能都需要大量修改现有代码,影响系统稳定性。分层架构通过清晰的层间接口,支持独立扩展。这解决了业务痛点"外部系统接口可能变化,需要支持灵活扩展"。
长期适配策略:
- 技术升级策略:当需要升级技术(如数据库迁移、外部系统升级)时,只需要修改对应的封装层,业务逻辑层不需要改动。
- 功能扩展策略:当需要增加新功能时,只需要在PD层增加新模块,调用现有层的接口,不需要修改其他层。
- 团队协作策略:不同团队可以负责不同的层(前端团队负责UI层,后端团队负责PD层,数据库团队负责DM层),职责清晰,互不干扰。
场景2:MailProxy系统的分层架构设计——从业务需求到架构落地
业务背景:某公司需要开发MailProxy系统,用于处理用户邮件请求,与Mail Server交互发送和接收邮件,与客户系统集成提供邮件服务,存储邮件数据到数据库。
业务痛点识别:
痛点1:需要与多种外部实体交互,技术细节复杂
- 需要处理用户邮件请求(Web界面)
- 需要与Mail Server交互(发送邮件、接收邮件)
- 需要与客户系统集成(提供邮件服务接口)
- 需要存储邮件数据到数据库(Oracle、SQL Server等)
- 如果业务逻辑直接处理这些交互,会导致业务逻辑与技术细节耦合,难以维护。
痛点2:外部系统接口可能变化,需要支持灵活扩展
- Mail Server可能更换(从Exchange换成Gmail),接口协议可能不同
- 客户系统可能升级,接口可能变化
- 数据库可能迁移(从Oracle换成SQL Server)
- 如果业务逻辑直接处理这些变化,会导致大量修改,风险高。
技术挑战:如何理解这个分层架构的设计思路?为什么这样分层?如何确保架构能够支持系统的长期演进?
解决方案:用分层架构解决业务痛点
第一步:识别业务痛点对应的外部实体
识别结果:
- 外部用户:用户(通过Web界面发送邮件)
- 外部系统:Mail Server(邮件服务器)、客户系统(需要集成的外部系统)
- 持久化存储:Oracle、SQL Server等数据库系统(存储邮件数据)
为什么这样识别:
- 外部用户:系统需要处理用户邮件请求,用户通过Web界面与系统交互,这是系统的核心用户交互方式。如果不识别,会导致无法设计UI层,业务逻辑需要直接处理Web请求,增加复杂度。
- 外部系统:系统需要与Mail Server交互(发送邮件、接收邮件),需要与客户系统集成(提供邮件服务),这是系统的重要外部集成。如果不识别,会导致无法设计SI层,业务逻辑需要直接处理邮件协议和HTTP接口,增加复杂度。
- 持久化存储:系统需要存储邮件数据,需要使用数据库,这是系统的数据存储需求。如果不识别,会导致无法设计DM层,业务逻辑需要直接处理数据库操作,增加复杂度。
第二步:用核心知识点拆解方案——根据外部实体设计分层架构
设计结果:
为什么这样设计:
展现层(UI层)——解决业务痛点"需要处理用户邮件请求"
- 设计决策:用户通过Web界面发送邮件,展现层封装Web界面的具体实现,为业务层提供统一的接口。
- 业务价值:当需要增加新的交互方式(如移动App)时,只需要增加新的展现层实现,业务逻辑层不需要改动。这解决了业务痛点"外部系统接口可能变化,需要支持灵活扩展"。
集成层(SI层)——解决业务痛点"需要与Mail Server和客户系统交互"
- 设计决策:系统需要与Mail Server交互(发送邮件、接收邮件),需要与客户系统集成(提供邮件服务接口),集成层封装这些具体交互方式,为业务层提供统一的接口。这对应四层架构中的SI层。
- 业务价值:当Mail Server更换(从Exchange换成Gmail)或客户系统升级时,只需要修改集成层,业务逻辑层不需要改动。这解决了业务痛点"外部系统接口可能变化,需要支持灵活扩展"。
业务层(PD层)——系统的核心,专注于业务逻辑
- 设计决策:业务层实现邮件处理逻辑(邮件路由、邮件过滤等),这是系统的核心。业务层不需要知道如何与用户交互、如何与Mail Server交互、如何访问数据库,只需要专注于业务逻辑的实现。这对应四层架构中的PD层。
- 业务价值:业务逻辑清晰、易于理解、易于测试、易于维护。新人可以快速理解"邮件路由"这个业务到底是怎么实现的,不需要关心邮件协议、HTTP接口、SQL语句等技术细节。这提高了开发效率,降低了维护成本。
数据访问层(DM层)——解决业务痛点"需要存储邮件数据"
- 设计决策:系统需要存储邮件数据,数据访问层封装数据库的具体操作,为业务层提供统一的数据访问接口。这对应四层架构中的DM层。
- 业务价值:当数据库迁移(从Oracle换成SQL Server)时,只需要修改数据访问层,业务逻辑层不需要改动。这解决了业务痛点"外部系统接口可能变化,需要支持灵活扩展"。
第三步:长期适配策略——分析设计的优点和长期价值
优点分析:
优点1:层次结构清晰,技术关注点分离——解决业务痛点"需要支持多人协作开发"
- 层次结构清晰:分层架构将系统划分为展现层、集成层、业务层、数据访问层,层次结构清晰,便于理解和维护。
- 技术关注点分离:每个层只负责一种技术关注点(用户交互、外部系统交互、业务逻辑、数据访问),不同层的代码互不干扰,便于开发和维护。
- 业务价值:如果所有代码混在一起(如业务逻辑和数据库操作混在一起),会导致代码混乱,难以理解和维护。分层架构通过关注点分离,使得每层代码独立,降低系统复杂度。这解决了业务痛点"需要支持多人协作开发,需要清晰的职责划分"。
优点2:基于分层架构进行分工,有利于技能专业化——提高开发效率
- 分工明确:程序员可以按照分层架构进行分工,分为UI组(负责展现层)、集成组(负责集成层)、业务组(负责业务层)、数据库组(负责数据访问层)。
- 技能专业化:每个组专注于一个技术领域(如UI组专注于前端技术,数据库组专注于数据库技术),有利于技能的专业化提升。
- 业务价值:如果每个程序员都需要掌握所有技术(前端、后端、数据库等),学习成本高,开发效率低。通过专业化分工,每个程序员专注于一个技术领域,可以提高开发效率和质量。这提高了团队的整体开发效率,降低了学习成本。
长期适配策略:
策略1:在层内进行细粒度模块划分——支持系统长期演进
- 当前状态:分层架构只解决了"如何分层"的问题,但没有解决"层内如何划分模块"的问题。例如,业务层可能包含多个业务模块(邮件路由、邮件过滤、邮件存储等),这些模块的划分需要在层内进行。
- 长期价值:在分层架构的基础上,在每层内进行细粒度模块划分。例如,业务层可以划分为邮件路由模块、邮件过滤模块、邮件存储模块等。这样既保持了分层架构的优势,又实现了细粒度模块划分,支持系统的长期演进。
- 实施建议:先确定分层架构(确定有哪些层),再在层内进行模块划分(确定每层有哪些模块)。一旦确定了分层架构,层内的模块划分就变得相对容易,因为每个层的职责已经明确。
总结收尾
通用应用逻辑公式
分层架构设计的通用逻辑可以总结为:“识别业务痛点→识别外部实体→设计封装层→验证合理性→长期适配策略”。
公式拆解:
- 识别业务痛点:系统需要与哪些外部实体交互?外部系统接口可能变化吗?需要支持多人协作开发吗?这些业务痛点决定了是否需要分层架构。
- 识别外部实体:通过上下文图识别系统需要与哪些外部实体交互(外部用户、持久化存储、外部系统/硬件、时限触发)。这就像盖房子,先确定需要哪些房间(需求),再设计房间布局(架构)。
- 设计封装层:为每种外部实体设计对应的封装层(外部用户→UI层,外部系统/硬件→SI层,持久化存储→DM层),然后设计业务逻辑层(PD层)。这解决了业务痛点"系统需要与多种外部实体交互,技术细节复杂"。
- 验证合理性:验证层间调用关系、职责清晰性、可扩展性,确保分层架构能够支持系统的长期演进。
- 长期适配策略:制定技术升级策略、功能扩展策略、团队协作策略,确保架构能够支持系统的长期演进。
可落地的交付物
分层架构设计检查清单:
-
上下文图识别:
- 识别了外部用户(终端用户、管理员)
- 识别了持久化存储设施(数据库、文件系统等)
- 识别了外部系统与底层硬件(外部系统、硬件设备)
- 识别了时限触发机制(定时任务)
-
分层架构设计:
- 设计了UI层(如果存在外部用户)
- 设计了SI层(如果存在外部系统或硬件)
- 设计了DM层(如果存在持久化存储)
- 设计了PD层(所有系统都需要)
-
层职责定义:
- UI层职责:封装用户交互(管理员界面、业务用户界面等)
- SI层职责:封装外部系统和硬件交互(与哪些外部系统交互、采用什么协议等)
- DM层职责:封装数据访问(使用什么数据库、如何访问文件等)
- PD层职责:实现业务逻辑(业务功能模块)
-
架构验证:
- 验证了层间调用关系(上层调用下层,不能跨层调用)
- 验证了职责清晰性(每层职责单一,没有职责重叠)
- 验证了可扩展性(新功能可以独立开发,不影响现有功能)
最简操作模板:
分层架构设计三步走:
1. 绘制上下文图,识别4种外部实体(外部用户、持久化存储、外部系统/硬件、时限触发)
2. 根据外部实体设计分层架构(外部用户→UI层,外部系统/硬件→SI层,持久化存储→DM层,业务逻辑→PD层)
3. 验证架构合理性(层间调用关系、职责清晰性、可扩展性)
回答核心问题
问题1:为什么需要分层架构?
核心原因:
- 封装外部交互:系统需要与多种外部实体交互(用户、数据库、外部系统、硬件),分层架构将这些交互封装到不同层次,让业务逻辑层专注于业务本身。
- 关注点分离:每个层只负责一种关注点(用户交互、业务逻辑、数据访问等),不同层的代码互不干扰,便于理解和维护。
- 提高可维护性:当外部交互方式改变时,只需要修改对应的封装层,业务逻辑层不需要改动。
适用场景:
- 需要封装外部交互:系统需要与用户、数据库、外部系统、硬件等多种外部实体交互。
- 需要支持多人协作:系统需要支持多人协作开发,需要清晰的职责划分。
- 需要支持扩展:系统需要不断演进,增加新功能,需要支持独立扩展。
问题2:如何设计分层架构?
设计方法:
- 从上下文图开始:通过上下文图识别系统需要与哪些外部实体交互(外部用户、持久化存储、外部系统/硬件、时限触发)。
- 设计封装层:为每种外部实体设计对应的封装层(外部用户→UI层,外部系统/硬件→SI层,持久化存储→DM层),然后设计业务逻辑层(PD层)。
- 验证合理性:验证层间调用关系(上层调用下层,不能跨层调用)、职责清晰性(每层职责单一)、可扩展性(新功能可以独立开发)。
设计原则:
- 一一对应:外部实体与封装层一一对应,外部用户→UI层,外部系统/硬件→SI层,持久化存储→DM层。
- 职责单一:每个层只负责一种关注点,职责清晰,便于维护。
- 标准调用:上层调用下层,不能跨层调用,降低系统复杂度。
记住:分层架构设计的核心是"知其所以然"——不是简单地模仿"三层架构"或"四层架构",而是理解"为什么需要这些层"“每层的职责是什么”“如何从需求出发设计分层架构”。正如温昱所说:“程序员向架构师转型,对分层架构当然得从’学样儿’开始,但应该力求尽早’悟道’——精通分层架构设计对架构师岗位太有必要了。”
参考:
《软件架构设计方法论》 温昱

被折叠的 条评论
为什么被折叠?



