下面以一个企业内容管理系统 (CMS) 为例,完整展示 SAAM 流程从开始到结束。SAAM 的核心是评估架构的可修改性,即应对未来变更的容易程度。
📘 SAAM 评估案例:企业内容管理系统 (CMS)
🧭 背景介绍
- 系统:企业 CMS(支持文章编辑、发布、分类、标签、多语言翻译、用户权限等)
- 架构:传统分层架构(前端 Vue + 后端 Spring Boot + MySQL),所有功能在一个单体应用中
- 评估目标 :评估该单体架构在未来两年内对各类变更的适应能力,识别高风险修改点
- 评估团队:评估组长 + 架构师 + 开发负责人 + 运维负责人 + 业务代表(共 6 人)
- 时间:1 天(工作坊形式)
阶段 1:描述架构(上午 09:00 - 10:00)
活动:架构师介绍当前系统的模块划分及依赖关系
CMS 架构简要视图:
- 表现层:Thymeleaf 模板 + 管理界面(Vue 独立部署)
- 业务层 :Spring Boot 单体,分为以下模块(代码层面):
article模块:文章 CRUD、发布、审核category模块:分类树管理tag模块:标签管理translation模块:多语言翻译(调用外部翻译 API)user模块:用户、角色、权限
- 数据层:MySQL 单库,表之间大量外键关联
- 部署:单机 Tomcat + Nginx 反向代理
评估组记录:模块间的强耦合点,例如:
article表直接引用category_id、author_id- 翻译模块直接调用
article表的content字段
阶段 2:开发场景(上午 10:00 - 12:00)
活动 :利益相关者(业务代表、开发、运维)提出未来可能发生的变更需求,形成场景列表。每个场景描述一个具体的修改要求。
头脑风暴产出的场景清单:
| 编号 | 场景名称 | 描述(变更内容) | 提出者 |
|---|---|---|---|
| S1 | 增加新的文章类型 | 增加"视频文章"类型,包含 video_url 字段,且视频文章不需要正文内容 | 业务代表 |
| S2 | 更换第三方翻译 API | 从百度翻译切换到阿里云翻译,API 签名方式、请求格式完全不同 | 开发负责人 |
| S3 | 文章审核流程增加二级审批 | 目前只有编辑审核,未来需要"编辑初审 + 主编终审"两阶段 | 业务代表 |
| S4 | 支持多种数据库 | 公司要求可选用 PostgreSQL 或 MySQL,目前代码中有大量 MySQL 特有语法(如 ON DUPLICATE KEY) |
运维负责人 |
| S5 | 文章标题长度限制从 50 改为 200 | 看起来很简单的字段长度修改 | 产品经理 |
| S6 | 增加全文检索功能(Elasticsearch) | 要求文章发布后自动同步到 ES,并提供搜索接口 | 架构师(预期变更) |
优先级投票 :每人 3 票,投给最可能发生的场景。
得票结果:S3(5票)、S1(4票)、S4(4票)、S2(3票)、S6(2票)、S5(1票)。
SAAM 重点分析得票高的前 3~4 个场景。
阶段 3:评估每个场景(下午 13:00 - 15:30)
活动:对每个高优先级场景,分析需要修改哪些组件,估算修改工作量、影响范围、潜在连锁反应。
▶ 场景 S1:增加"视频文章"类型
分析:
- 数据库:
article表增加video_url字段(允许 NULL),新增article_type字段(0=普通,1=视频) - 后端:
Article实体类加字段,save()方法中根据类型跳过正文内容校验 - 前端:文章编辑页面增加"视频文章"选项,展示视频 URL 输入框
- 审核逻辑:视频文章不需要审核正文,但需要审核视频链接是否可播放
影响预估:
- 需修改文件:数据库 DDL、实体类、Service 层校验逻辑、前端页面、审核页面
- 工作量:3 人日(中等)
- 潜在风险:若未来增加更多文章类型(音频、PDF),每次都改
article表,导致表过宽 → 设计上缺乏扩展性
评估结论:单体架构可完成,但扩展性差(对"增加新类型"敏感)。
▶ 场景 S3:增加二级审批(编辑初审 + 主编终审)
分析:
- 数据库:
article表需增加first_reviewer、second_reviewer、review_status(细化:待初审、初审通过、待终审、终审通过等) - 后端:原来的
review()接口需要拆分为firstReview()和finalReview(),增加权限校验(主编才能终审) - 工作流引擎:目前没有状态机,完全用
if-else实现,修改复杂 - 前端:审核界面需展示不同步骤的审核人及意见
影响预估:
- 大量修改现有审核模块,影响 8+ 个文件,且易引入 bug(例如终审前文章又被退回初审)
- 工作量:10 人日(高)
- 风险:高,因为原设计没有考虑多级审批,硬编码扩展困难
评估结论:单体架构下修改成本高,且容易破坏现有功能。
▶ 场景 S4:支持多种数据库(MySQL ↔ PostgreSQL)
分析:
- 检查现有 SQL:发现使用了
ON DUPLICATE KEY UPDATE、GROUP_CONCAT、LIMIT等 MySQL 特有语法 - 依赖:JPA/Hibernate 部分原生查询写死 MySQL 方言
- 需要改动:所有 DAO 层的原生 SQL 替换为标准 SQL,或使用数据库抽象层
- 测试:需要在两种数据库环境分别测试所有数据访问路径
影响预估:
- 影响 20+ 个 DAO 方法,大量 SQL 重写
- 工作量:15 人日(很高)
- 风险:回归测试范围极大,可能引入隐藏的兼容性问题
评估结论:当前架构对数据库强耦合,修改代价很大。
▶ 场景 S2:更换翻译 API(百度 → 阿里云)
分析:
- 翻译模块独立为一个
TranslationService类,内部封装 HTTP 调用、签名生成 - 更换 API 只需修改该类中的请求构造和响应解析,其余调用方(文章翻译时)无感知
- 工作量:1 人日(低)
- 风险:低,模块封装较好
评估结论:该变更容易实现,架构对这类变更支持良好。
阶段 4:评估场景交互(下午 15:30 - 16:30)
活动:分析多个场景同时发生时,是否有叠加影响,或者一个场景的修改会影响另一个场景的评估。
发现的交互:
- S1(增加视频文章) + S3(二级审批):如果同时实现,审核状态机需要区分普通文章和视频文章的审核流程 → 复杂度非线性增加。
- S4(多数据库) + 任何其他场景:如果在改造数据库抽象的过程中同时做其他修改,会极大增加冲突风险,建议分批进行。
场景组合风险评级:
- S1 + S3 同时修改:高冲突风险,因为会同时改动
article表结构和工作流逻辑,建议先做 S3 重构工作流状态机,再支持新文章类型。
阶段 5:形成总体评估结论(下午 16:30 - 17:30)
产出物:
1. 架构强点(对哪些变更容易适应)
- 翻译 API 替换(S2):封装良好,轻松修改
- 文章标题长度修改(S5):仅字段校验修改,成本极低
2. 架构弱点(对哪些变更敏感)
| 变更类型 | 敏感组件 | 严重性 | 建议 |
|---|---|---|---|
| 增加新文章类型 | article 表 + 前端表单 | 中 | 考虑 EAV 模型或 JSON 字段 |
| 增加审批流程阶段 | 审核模块(硬编码状态) | 高 | 引入状态机/工作流引擎 |
| 更换数据库 | DAO 层原生 SQL | 高 | 抽象数据访问层,使用 JPA 标准方言 |
| 增加全文检索 | 无现有扩展点 | 中 | 预留文章发布事件,解耦同步逻辑 |
3. 架构耦合度分析
- 业务层与数据库强耦合(表外键、特有 SQL)
- 审核逻辑硬编码状态,缺乏灵活性
- 文章类型缺少扩展设计
4. 总体可修改性评分(定性)
- 低变更成本:接口替换、字段长度修改
- 中等变更成本:增加字段或简单逻辑
- 高变更成本:工作流变更、数据库迁移、多类型内容支持
最终建议:
- 短期接受单体架构,但需重构审核模块为状态机模式
- 中期考虑将文章内容与元数据分离,支持灵活的内容类型扩展
- 长期若有更多数据库异构需求,应引入数据访问抽象层或迁移至 JPA 标准查询
✅ SAAM 流程总结(CMS 案例)
| 阶段 | 主要产出 |
|---|---|
| 描述架构 | 模块依赖图、强耦合点记录 |
| 开发场景 | 6 个未来变更场景,优先级排序 |
| 评估每个场景 | 修改范围、工作量、风险等级(S1-S4 详细分析,S2 低风险,S5 低) |
| 评估场景交互 | S1+S3 高风险组合,S4 与其他隔离建议 |
| 结论 | 架构强点、弱点、敏感组件、改进建议 |
这个 SAAM 例子展示了如何通过具体变更场景来验证架构的可修改性,并识别出需要重构的"热点模块"。它与 ATAM 的区别在于:没有涉及多质量属性权衡(如性能 vs 安全性),只专注于回答"改起来难不难?"。