{T}

架构-系统的概要设计

导言:概要设计——从混沌到秩序的关键一步

在软件工程实践中,有一个被反复验证的规律:系统 70% 的缺陷源于概要设计阶段的决策失误。概要设计(High-Level Design)是架构师最核心的工作产出——它将需求规格说明中的"做什么"转化为技术方案中的"怎么做",同时为详细设计和编码划定边界。

许式伟在本节中提出的核心问题是:概要设计到底要设计什么?写到什么深度?如何验证其正确性?

关联阅读:本节是方法论层面的总结,将第 18-31 讲的所有架构实践统一到概要设计的框架中。建议结合第 17 讲"软件工程与架构师角色"中关于架构师职责的讨论来理解。


一、概要设计的本质与定位

1.1 概要设计在工程流程中的位置

图表渲染中…

概要设计的输入是需求规格说明,输出是系统分解方案和关键接口定义。它不是详细设计——不涉及算法选择、数据结构细节——但它是详细设计的约束和指南。

1.2 概要设计 vs 详细设计

维度概要设计详细设计
关注点模块分解、接口定义、数据流向算法、数据结构、具体实现
受众架构师、技术负责人开发工程师
变更成本极高(影响全局)中等(影响局部)
验证方式评审、原型、推演单元测试、集成测试
抽象层次模块/子系统级类/函数级

1.3 概要设计的三个核心问题

许式伟将概要设计归纳为回答三个核心问题:

  1. :系统如何分解为模块?(模块化)
  2. :模块之间如何协作?(接口与交互)
  3. :系统如何应对未来的变化?(可扩展性)
图表渲染中…

二、系统分解:从整体到模块

2.1 分解的方法论

系统分解不是随意的切割,而是遵循明确的方法论。许式伟推荐的分解方法:

图表渲染中…

2.2 以画图程序为例的分解过程

图表渲染中…

2.3 模块依赖规则

分解后必须定义模块间的依赖规则——哪些模块可以依赖哪些模块:

图表渲染中…

依赖规则:界面模块依赖核心模块,核心模块依赖基础设施;反向依赖被禁止。这保证了核心模块的可测试性和可复用性。


三、接口设计:模块间的契约

3.1 接口的三个层次

许式伟将接口分为三个层次:

层次内容示例
API 接口函数签名、参数、返回值Document.addShape(Shape): void
协议接口通信格式、序列化规则JSON Schema、Protobuf 定义
行为接口语义约束、不变式"addShape 后 shapes.length 必定 +1"
图表渲染中…

3.2 接口设计的原则

  1. 最小化原则:接口暴露的越少越好,内部实现细节不应泄漏
  2. 稳定性原则:接口一旦发布就应保持稳定,变更必须向后兼容
  3. 完备性原则:接口应覆盖所有合法使用场景,不迫使使用者"绕过"接口

3.3 接口的文档化

概要设计文档中,接口描述应包含:

图表渲染中…

四、概要设计文档的结构

4.1 推荐的文档模板

许式伟推荐的概要设计文档包含以下核心章节:

图表渲染中…

4.2 各章节的深度要求

章节深度要求常见错误
系统概述一张架构图 + 三段话说明设计哲学过于笼统,缺乏决策依据
模块分解每个模块一段职责描述 + 依赖图只有列表没有依赖关系
接口定义核心 API 的签名 + 行为约束只写函数签名不写语义
关键场景核心用例的序列图场景覆盖不全
开放问题明确列出未决事项回避问题,假装设计已完成

4.3 关键场景的推演

以画图程序"绘制矩形"为例,概要设计中的场景推演:

图表渲染中…

场景推演的目的:验证模块分解和接口定义是否足以支撑核心流程。如果推演中需要"绕过"某个接口,说明设计有缺陷。


五、概要设计的验证

5.1 验证方法

图表渲染中…

5.2 变化点分析

许式伟特别强调变化点分析——这是概要设计区别于编码的关键价值:

变化场景预期影响范围如果影响范围过大
新增一种图形只加一个 Shape 子类Shape 体系设计有问题
新增一种工具只加一个 Tool 子类Tool 接口设计有问题
修改文件格式只改序列化层持久化泄漏到了核心层
替换渲染引擎只改 Graphics 实现渲染抽象层不够
新增同步功能只在 Model 层增厚Model 和 View/Controller 耦合了

六、设计原则与权衡

6.1 概要设计的核心权衡

决策点方案 A方案 B选择
设计深度足够详细适度抽象适度抽象——过细则与详细设计重复
文档形式正式文档轻量 Wiki核心系统用正式文档,辅助系统用 Wiki
验证时机设计完成一次性验证持续验证持续验证——设计是迭代过程
接口粒度细粒度粗粒度核心接口细粒度,辅助接口粗粒度
变更策略设计冻结允许演进允许演进但有变更评审

6.2 反模式:概要设计沦为形式

最常见的反模式是把概要设计文档当作"交付物"而非"思考工具":

  • 复制粘贴需求文档作为"系统概述"
  • 只画架构图不定义接口
  • 不做场景推演就进入编码
  • 文档写完就束之高阁,与代码脱节

正确态度:概要设计是活的文档——它应该在编码过程中持续更新,反映架构的实际状态。

6.3 许式伟的概要设计心法

  1. 先分后合:先做模块分解,再定义接口——顺序不能反
  2. 场景驱动:用核心场景推演验证设计,而非凭空想象
  3. 适度设计:概要设计解决 80% 的架构问题,剩余 20% 在详细设计中解决
  4. 文档即思维:写文档的过程就是思考的过程,不是为了交差
  5. 持续演进:设计不是一次性活动,是持续迭代的过程

小结与关键要点

要点说明
三个核心问题分(模块化)、合(接口与交互)、变(可扩展性)
系统分解按业务概念边界划分,定义依赖规则,禁止反向依赖
接口三层API接口(语法)、协议接口(编码)、行为接口(语义)
场景推演用核心用例验证设计,发现缺陷及时迭代
变化点分析预判需求变化的影响范围,验证模块化的有效性
活文档概要设计是思考工具,不是交付物,应持续演进

关联阅读:下一篇(第 33 讲)将对整个桌面开发篇做回顾与总结,构建完整的知识体系地图。