3.2 Software Architecture and Design(整理版)
原始笔记: Software Design.md 原始教程: 3.2 Software Architecture and Design created: 2026-07-27 10:25 整理说明: 本版本保留原笔记中的设计取舍、架构图、MVC、设计准则与重构建议,仅补充理解这些知识点所需的说明。
内容简要概括
软件设计需要在设计不足与过度设计之间取得平衡,目标不是提前预测所有未来需求,而是为当前问题建立清晰、可测试、易于修改的结构。软件架构可以通过组件与接口图表达系统的高层职责;MVC 等模式提供参考词汇,但最终仍应选择最符合实际使用方式的简单方案。
软件设计、Software Architecture、技术债务、组件、接口、MVC、Model、View、Controller、关注点分离、自动化测试、重构
目录
- 1. 设计的平衡
- 2. 检查项目分支
- 3. Software Architecture
- 4. 架构设计练习
- 5. MVC Architecture
- 6. Architectural Design Guidelines
- 7. 通过测试保护重构
1. 设计的平衡
软件设计需要面对几组现实取舍:
- 完全不设计,容易积累技术债务;
- 设计过度,可能把时间浪费在尚未出现的问题上;
- 需求会变化,初始设计不可能永久正确;
- 合理目标不是一开始写出完美代码,而是写出当前足够好、易于修改的代码。
更稳健的开发策略是:
适度设计
→ 小步实现
→ 自动化测试
→ 持续重构
1.1 技术债务
为了尽快交付而选择容易但受限的方案,可能让软件逐渐变得复杂、难以理解和难以维护。未来修改时付出的额外成本,就是技术债务带来的“利息”。
技术债务不一定能够完全避免,但需要在维护过程中持续偿还,例如简化结构、消除重复、澄清命名和补充测试。
2. 检查项目分支
原笔记保留了用于查看 Git 分支的命令:
git branch --all
git branch:列出本地分支;--all:同时显示本地分支和远程跟踪分支。
这条命令只读取分支信息,不会切换或修改分支。
3. Software Architecture
软件架构描述系统的高层结构,包括:
- 系统有哪些主要组件或模块;
- 每个组件负责什么;
- 组件之间如何交互;
- 系统如何与用户、数据库或外部服务协作。
架构设计可以先用“方框 + 连线”画出结构。图不需要包含所有实现细节,它的作用是帮助团队讨论职责、数据流和接口。
3.1 方框表示组件
每个方框可以代表:
- 一个代码模块;
- 一个服务;
- 用户;
- 数据库;
- 外部系统。
例如:
[用户] → [Web 界面] → [分析模块] → [数据库]
这样可以直观看出系统由哪些部分组成,以及每一部分承担什么职责。
3.2 连线表示接口
组件之间的连线可以表示:
- 数据传递;
- 函数调用;
- 控制流程;
- 网络请求。
例如:
[文件读取模块] ──数据──> [计算模块]
连线不只表示“两个模块有关”,还需要考虑:
- 传递什么信息;
- 信息格式是什么;
- 谁调用谁;
- 是否需要返回结果。
这些交互约定构成系统的接口。明确接口可以减少组件之间不必要的依赖,使不同组件更容易独立修改和测试。
4. 架构设计练习
4.1 需求
为下面的新功能绘制高层架构:
用户把新的炎症数据上传到一个 Google Drive 文件夹后,软件自动下载数据并更新分析;新结果连同时间戳写入数据库;随后向群组邮件列表发送更新通知。
可以手绘,也可以使用 Excalidraw 等绘图工具。
4.2 原笔记中的解答

读图约定:
- 矩形:处理模块或服务;
- 圆柱体:数据存储;
- 箭头:调用、触发或数据流;
- 箭头旁文字:接口、数据或触发方式。
这张图需要表达的核心流程是:
Google Drive 中出现新数据
→ 拉取数据
→ 更新分析
→ 将带时间戳的结果写入数据库
→ 发送邮件通知
绘制这种图时,应重点检查各组件的职责是否明确、数据在哪些边界间流动,以及外部系统失败时会影响哪些步骤。
5. MVC Architecture
Model-View-Controller(MVC)把相关逻辑划分为三个相互协作的部分:
| 组件 | 主要职责 |
|---|---|
Model |
管理数据和业务逻辑 |
View |
展示信息并提供用户可见的交互界面 |
Controller |
接收输入,协调 Model 与 View |
5.1 Model
Model 保存和处理应用的数据与核心规则。它不应依赖数据最终如何展示。
5.2 View
View 是用户看到和操作的界面,可以是 GUI,也可以是 CLI 中的文本输出和选项。View 应尽量避免承载复杂业务逻辑。
5.3 Controller
Controller 接收输入并触发相应操作:调用 Model 更新或读取数据,再协调 View 展示结果。
MVC 是架构模式而不是必须严格遵守的规则。实际应用中,View 和 Controller 的边界可能不完全清晰;关键是有意识地分离数据与业务逻辑、展示层和输入协调职责。
6. Architectural Design Guidelines
良好的软件架构不是机械套用规则或模式,而是根据实际问题做出清晰、适度的设计决策:
- 写代码前与同事讨论设计;
- 把不同关注点放入不同代码区域;
- 避免重复代码或重复数据;
- 尽量减少一个人同时必须理解的信息量;
- 避免过多抽象;如果阅读代码时需要频繁跳转,可能已经抽象过度;
- 明确组件之间以及组件与外部系统之间的接口;
- 不为尚未出现的未来需求设计“永不过时”的方案;
- 选择能够解决当前问题的最简单方案;
- 修改结构较差的代码前,先小步重构,使新变化能够自然融入;
- 离开代码时,让它比接手时更清晰一些。
这些准则共同服务于几个目标:可理解、可修改、可测试和可维护。
7. 通过测试保护重构
7.1 重构前最好有测试
重构要求外部行为保持不变。如果没有测试,很难判断结构调整是否意外改变了结果。
推荐流程:
为现有行为补测试
→ 小步重构
→ 每一步运行测试
→ 确认行为不变
7.2 重构应当小步进行
不建议一次重写整个项目。更可靠的方式是:
改一个名字
→ 运行测试
→ 提取一个函数
→ 运行测试
→ 消除一处重复
→ 运行测试
小步重构有两个直接好处:
- 出错时容易定位;
- 每一步都容易审查和回滚。