Hofmeister 4 视图模型彻底讲透:别再和 Kruchten 4+1 搞混了

刷了三套真题, Hofmeister 还是错。题干一换说法就懵:到底哪个视图管功能、哪个管并发?

这篇就是为解决这个痛点写的。系统架构师考试里,Hofmeister 四视图和 Kruchten 4+1 视图是高频混淆点,出题人就爱在这里设陷阱。目标很直接:理解了原理,后面自然不会忘。

这篇文章把两个模型放在同一语境下讲透:Hofmeister 为何要分四层、每一层在回答什么问题、为何与 Kruchten 的 4+1 形似而神不同,并用同一选课系统贯穿两个模型,最后用三类场景聚类验证。

先把最容易错的结论放前面

  • Hofmeister 4 视图(Siemens 四视图):Christine Hofmeister 等人在 Siemens 大型系统实践中总结,4 个视图——概念、模块、执行、代码。关注如何从业务逐层追溯到源码。
  • Kruchten 4+1 视图:Philippe Kruchten 在 Rational 提出,5 个视图——逻辑、开发、进程、物理 + 场景(用例)视图。关注如何让不同干系人从各自视角验证同一架构。

两者的 +1 是关键分野:Kruchten 的场景视图(Scenarios)本质就是用例视图(Use Case View),用例是类型、场景是实例,4+1 语境下视为同一视图,用一条代表性用户故事把其余四视图串起来做一致性验证;Hofmeister 没有这个视图。

flowchart LR subgraph Hof["Hofmeister 4视图 (Siemens)"] H1[概念视图<br/>Conceptual] H2[模块视图<br/>Module] H3[执行视图<br/>Execution] H4[代码视图<br/>Code] end subgraph Kru["Kruchten 4+1视图"] K1[逻辑视图<br/>Logical] K2[开发视图<br/>Development] K3[进程视图<br/>Process] K4[物理视图<br/>Physical] K5[场景/用例视图<br/>Scenarios<br/>+1] end Hof -.形似而神不同.- Kru

很多资料把两者画等号,考试就考这个误区。概念与逻辑、模块与开发、执行与进程、代码与物理,虽有对应但抽象层次和关注点并不等价。

Hofmeister 为何要分四层

Hofmeister 回答的是:一个大系统,如何让不同角色各自看懂自己关心的部分,又能互相映射?

它的答案是一个漏斗:抽象程度递减,从最抽象的领域概念,一步步落地到磁盘上的文件。

flowchart TB C[概念视图<br/>系统是什么<br/>领域能力与关系] --> M[模块视图<br/>如何分而治之<br/>分层与依赖] M --> E[执行视图<br/>跑起来会怎样<br/>进程线程与并发] E --> D[代码视图<br/>源码如何安放<br/>文件包与构建] style C fill:#dbeafe style D fill:#fef3c7

越往上越抽象、越贴近业务;越往下越具体、越贴近机器。理解这个递进,后面每个视图的定位就自然成立。

Hofmeister 四视图逐层拆开

1. 概念视图——回答“系统是什么”

想象你要给完全不懂技术的业务方讲系统。你不会说“我们用 MySQL 分库”,你会说“系统里有选课、课程、通知三个能力,选课依赖课程,选课完成会触发通知”。这就是概念视图:把系统抽象成一组职责清晰的黑盒组件及连接器,不关心盒子内部如何实现。

为何需要它:大型系统最先要对齐业务边界,若一开始就讨论分层和进程,业务概念与技术实现会搅在一起,需求一改就牵一发动全身。它面向领域专家与架构师,产出是概念组件图与领域模型。

如何辨别:只要讨论还停留在能力、职责、领域关系,尚未涉及如何拆模块、如何并发、如何放文件,就是概念视图。

类比房子的户型图:只说几室几厅、客厅连阳台,不说砖怎么砌。

2. 模块视图——回答“如何分而治之”

业务方点头后,设计师要接手:这些能力如何分解为可开发、可复用的模块?哪些放一起、哪些分开?接口如何定义?层次如何划分才能让通用部分被复用、易变部分被隔离?这就是模块视图,是连接业务与实现的桥梁。

它与概念视图的区别在于:概念说“有选课能力”,模块说“选课能力由选课模块、缓存模块、消息模块协作实现,选课模块依赖缓存接口”。前者是有什么,后者是怎么拆。它面向设计师与项目管理者,产出是模块分解图、分层图与接口定义。

它与 Kruchten 开发视图的区别也源于此:模块视图关注设计期的职责分层与复用,开发视图更关注源码包如何组织以支撑团队并行开发。

3. 执行视图——回答“跑起来会怎样”

模块分好,系统尚未运行。启动后会产生几个进程?哪些是常驻、哪些是 Worker?它们如何通信、同步、调度?高并发时在哪里排队、哪里加锁?这就是执行视图,唯一讨论“活的系统”的视图。

为何必须独立:静态分解再好,跑起来也可能死锁、超卖、堆积。执行视图把时间维度加进来,评估性能与可靠性。它面向系统工程师,产出是进程图与并发模型。

如何辨别:只要涉及进程、线程、任务、并发、同步、通信、调度,就是执行视图。它与物理视图的本质区别是:执行关心行为(如何协作),物理关心地点(部署在哪)。

4. 代码视图——回答“源码如何安放”

系统要交付,源码不能散落。哪些文件放同一目录、哪些打成一个库、谁依赖谁、如何编译构建与版本管理?这就是代码视图,最贴近磁盘的一层。

为何不能并入模块:模块是逻辑分解,代码是物理存放。同一模块可能对应多包,多模块也可能编译进同一库。配置管理员关心的是后者。它面向开发者与构建工程师,产出是代码组织与构建依赖图。

flowchart TB subgraph 维度["抽象 ←→ 具体 / 静态 ←→ 动态"] direction TB C2["概念视图<br/>抽象 · 静态结构"] --- M2["模块视图<br/>抽象 · 静态分解"] E2["执行视图<br/>具体 · 动态行为"] --- D2["代码视图<br/>具体 · 静态组织"] C2 --- E2 M2 --- D2 end

概念与模块偏静态抽象,执行偏动态具体,代码偏静态具体。理解这个象限,就理解了为何执行视图是唯一动态的。

Kruchten 4+1 视图:同一问题,另一种组织方式

若说 Hofmeister 是纵向漏斗,Kruchten 就是横向拼盘加中心串联。它同样要让不同角色看懂架构,但组织逻辑是:四视图并列,各服务一类干系人,再用场景/用例视图把四者串起来验证。

flowchart TB subgraph Hof2["Hofmeister · 漏斗递进"] HC1[概念] --> HC2[模块] --> HC3[执行] --> HC4[代码] end subgraph Kru2["Kruchten · 拼盘+串联"] K1[逻辑<br/>类/对象] --- K2[开发<br/>包/分工] K3[进程<br/>并发/性能] --- K4[物理<br/>节点/部署] K5[场景/用例视图 +1<br/>用代表性用例串联验证] K1 -.验证.-> K5 K2 -.验证.-> K5 K3 -.验证.-> K5 K4 -.验证.-> K5 end
维度Hofmeister 4 视图Kruchten 4+1 视图
提出背景Siemens 大型长周期系统Rational 面向对象与 UML
组织逻辑漏斗递进,抽象到具体拼盘并列,场景居中串联
核心关切如何逐层追溯到代码如何让多视角一致
部署描述弱,含于代码/执行强,物理视图独立
用例驱动无显式场景视图有,场景即用例视图

一句话区分:题干强调逐层细化、追溯,多为 Hofmeister;强调多视角、一致性验证,多为 Kruchten。

优缺点

Hofmeister 优点:贴合大型复杂系统,递进关系清晰便于追溯与分工。不足:缺少场景串联,需求可追溯性弱;部署描述单薄;对小系统偏重。

Kruchten 优点:干系人覆盖全,场景驱动能发现视图间不一致,物理视图对分布式友好。不足:视图边界易重叠,缺少递进感,非面向对象系统表达力弱。

两者无绝对优劣,是出身决定形态:Siemens 关注长周期可追溯,Rational 关注多角色协同验证。

同一系统,两套视角:校园选课贯穿示例

假设同一选课系统(2 万人抢课),分别用两套模型描述,会看到关注点的平移。

Hofmeister 视角的选课系统

flowchart LR S[学生] --> C1[选课服务<br/>选课/退课/查询] T[教师] --> C2[课程管理<br/>发布/审核] A[管理员] --> C3[系统管理<br/>权限/报表] C1 <--> C4[数据服务<br/>成绩/课表] C2 <--> C4 C1 -.事件.-> C5[通知服务]

概念视图只说有什么能力及关系,不讨论 Java 还是 Go。

flowchart TB subgraph UI[表示层] Web[Web前端] App[移动端] end subgraph Biz[业务逻辑层] Course[课程模块] Select[选课模块] User[用户模块] end subgraph Sup[支撑层] Auth[认证] Msg[消息队列] Cache[缓存] end subgraph Data[数据层] DB[(数据库)] end Web --> Course & Select Course --> DB Select --> Cache --> DB Select --> Msg

模块视图回答如何分层与依赖,决定团队分工与复用。

sequenceDiagram participant B as 浏览器 participant NG as Nginx进程 participant P1 as 选课进程池 participant Q as Redis队列 participant W as 异步Worker B->>NG: 高并发抢课 NG->>P1: 负载均衡 P1->>Q: Lua原子扣减 Q-->>P1: 成功/失败 P1-->>B: 立即返回 Q->>W: 异步落库 W->>W: DB事务提交

执行视图回答运行时如何通过进程池、原子操作与异步削峰保障性能。

flowchart TB root[campus-select/] root --> src[src/] src --> course[course/] src --> select[select/] src --> common[common/auth cache] course --> c1[course.go] select --> s1[select.go<br/>lua/deduct.lua] root --> pkg[Dockerfile/Makefile]

代码视图回答源码如何组织与构建。

Kruchten 视角的同一选课系统

同一系统换 Kruchten 组织,内容会这样平移:

  • 逻辑视图:以类/对象呈现,与 Hofmeister 概念视图对应但更具体——StudentCourseEnrollment 类及其关联、选课规则的状态机;用类图与序列图表达功能实现逻辑。
  • 开发视图:以包与子系统呈现,与模块视图对应但更贴近工程——com.campus.coursecom.campus.enrollmentcom.campus.common 包,定义团队分工与依赖,强调编译与复用边界。
  • 进程视图:与执行视图最接近——选课进程池、消息消费者进程、定时任务进程的并发与同步,关注吞吐与死锁,与 Hofmeister 执行视图几乎重合。
  • 物理视图:Hofmeister 所弱化的部分在此独立——Nginx 节点、应用节点、Redis 集群、MySQL 主从的部署拓扑与网络约束,这是两者最大分野。
  • 场景/用例视图(+1):用一条代表性用例把前四视图串起来,例如“学生高峰期抢课”——从逻辑的选课规则,到开发的包依赖,到进程的并发策略,到物理的节点部署,用同一用例验证四者是否一致。这正是 Hofmeister 所缺的闭环。
flowchart TB UC["场景/用例:高峰期抢课<br/>前置:课程有余量<br/>主流程:校验→扣减→下单→通知<br/>备选:余量不足→排队"] UC --> L["逻辑:Enrollment 校验规则"] UC --> D["开发:enrollment 包依赖 cache"] UC --> P["进程:Lua 原子+异步落库"] UC --> PH["物理:应用多实例+Redis集群"] L -.一致性.-> D D -.一致性.-> P P -.一致性.-> PH

理解这个平移,就理解了为何考试常把两者对照:同一系统,Hofmeister 问如何一层层落地,Kruchten 问如何用一条用例验证多视角是否自洽。

聚类验证:换三个场景再走一遍漏斗

单一例子易成背诵,聚类才能验证理解。同样的四层漏斗,装进不同领域,变形的是内容,不变的是分层逻辑。

场景 A:电商秒杀(写密集)

视图关注点例子
概念能力与关系商品、库存、订单、支付;库存与订单强一致
模块分解与分层接入层→业务层→支撑层→数据层;秒杀依赖库存接口
执行运行时并发网关→进程池→Redis 原子扣减→Kafka 削峰→异步落库
代码源码组织flashsale/{internal/seckill, pkg/lua},Lua 独立版本

场景 B:智慧停车 IoT(设备与边缘)

视图关注点例子
概念能力与关系车位感知、计费、导航;车位事件流
模块分解与分层设备抽象层→边缘网关→云端服务;强调协议可替换
执行运行时并发边缘多线程采集→MQTT 上云→流处理聚合;关注断网重连
代码源码组织parking/{edge, cloud, device/drivers},驱动以 .so 分仓

场景 C:企业 OA 审批(流程密集)

视图关注点例子
概念能力与关系表单、流程引擎、组织架构;表单驱动流程
模块分解与分层表单设计器→流程引擎→权限→集成;引擎为复用核心
执行运行时并发引擎多线程调度→定时器扫超时→消息推待办;重状态一致性
代码源码组织oa/{workflow, form},流程定义以 JSON 版本化
flowchart TB subgraph 概念层 A1[秒杀:商品/订单] B1[停车:感知/计费] C1[OA:表单/流程] end subgraph 模块层 A2[秒杀:分层+库存接口] B2[停车:设备抽象+网关] C2[OA:流程引擎复用] end subgraph 执行层 A3[秒杀:进程池+削峰] B3[停车:边缘多线程+重连] C3[OA:引擎线程+状态一致] end subgraph 代码层 A4[秒杀:lua版本] B4[停车:驱动.so分仓] C4[OA:JSON版本化] end A1 --> A2 --> A3 --> A4 B1 --> B2 --> B3 --> B4 C1 --> C2 --> C3 --> C4

体会这个对比:概念层看领域名词如何变,模块层看分层依据如何变,执行层看并发矛盾在何处,代码层看何物需独立版本。四问一对,换皮不慌。

常见混淆辨析

  • 概念 vs 模块:擦掉实现还能讲清吗?能,是概念;需讲谁依赖谁才说得清,是模块。
  • 模块 vs 代码:逻辑分几块是模块,物理放几处是代码。
  • 执行 vs 物理:跑起来如何协作是执行,部署在何处是物理;后者仅 Kruchten 独立。
  • 为何 Hofmeister 无 +1:Siemens 更重逐层可追溯,Rational 更重多视角串联验证,出身决定形态。

做题时先问:题干在讨论系统的哪个阶段?对齐业务、做分解、评估运行时、还是组织源码?阶段对了,答案自然对。

小结

Hofmeister 的价值不在四个名词,而在漏斗本身:从是什么,到怎么拆,到跑起来如何,到怎么放。Kruchten 的价值不在多一个视图,而在用一条用例把多视角拉通验证。理解这两条设计意图,远比记忆口诀可靠。

下次遇到视图题,不妨先还原系统所处阶段,再映射到对应视图;若题干提及用例串联与物理部署,自然联想到 4+1。这样学来,方是真正学会。

架构视图本质是视角,不是图纸。视角对了,图纸自然对。

参考

  • Hofmeister, Nord, Soni - Applied Software Architecture (Siemens 四视图原始文献)
  • Philippe Kruchten - The 4+1 View Model of Architecture
  • 软考系统架构师历年真题中“视图模型”相关考点

版权声明: 本文首发于 指尖魔法屋-Hofmeister 4 视图模型彻底讲透:别再和 Kruchten 4+1 搞混了https://blog.thinkmoon.cn/post/999-arch-hofmeister-4views-model/) 转载或引用必须申明原指尖魔法屋来源及源地址!