02-软件开发的最小闭环
软件开发的最小闭环:自顶向下设计、自底向上实现、步步可验证
软件开发的核心不是「设计 → 全部实现 → 最后一次运行」,而是一圈圈可验证的最小闭环:自顶向下设计(整体结构先定),自底向上实现(从最底层最可验证的单元开始),每一步都是「动作 → 产生结果 → 验证结果 → 解锁下一步」。编程学习也是一样——一个个可以不断编码、执行、验证的最小闭环。这一篇讲最小闭环在软件开发里怎么落地。
一、先看反面:为什么「全部写完再运行」会失败
1 | ❌ 错误流程: |
问题:每一步都没有验证,错误堆积到最后一次性爆发。 等系统复杂以后,「最后一次运行」几乎必然痛苦。
1 | ✅ 正确流程: |
设计可以大,实现必须小步。 每一步都落在某个闭环里,才谈得上「可验证」。
二、自顶向下设计:先定结构
设计方向是自顶向下——整体先定:
1 | 需求 |
1 | Game |
自顶向下设计 = 先画整体结构,再逐层细化。 它可以是一张完整的架构图,但实现时不需要全部写完。
三、自底向上实现:从最可验证的开始
实现方向和设计方向相反——自底向上:
1 | 设计方向(自顶向下):整体 → 系统 → 子系统 → 组件 → 接口 |
为什么?上层依赖下层,下层不依赖上层——所以实现时天然从底层、最可验证的单元开始:
1 | Game |
真正写代码可能就是:
1 | Vector2(测试通过)→ AABB(测试通过)→ Collision(测试通过) |
每一步都先验证再往上——这就是自底向上实现 = 一圈圈扩大的闭环。
四、步骤必须是可验证的闭环
自顶向下设计给出「要做什么」,但真正的工程步骤不能只有「先后」——每个步骤必须可验证:
| Step | 工作项 | 前置依赖 | 验证 |
|---|---|---|---|
| 1 | Vector2 | 无 | 加减乘正常 |
| 2 | Entity | 无 | 能创建/销毁 |
| 3 | Component | Entity | 能挂载 |
| 4 | Registry | Entity+Component | 增删查正常 |
| 5 | System | Registry | 能遍历实体 |
| 6 | Movement | System+Transform | 方块能移动 |
| 7 | Collision | Movement | 不穿透 |
| 8 | Render | Transform | 能显示 |
| 9 | Game | 全部 | 能运行 |
于是它不只是「先做 A 再做 B」,而变成:
A 完成并通过验证 → 才允许进入 B。
最有用的单位不是「模块」,而是可验证的步骤:
1 | 动作 → 产生结果 → 验证结果 → 解锁下一步 |
不要写「实现 ECS」——这个太大,做完不知道算不算完成。拆成:
1 | 创建 Entity → 能够生成 ID → 能够销毁 ID → 写测试 → 通过 |
一个好步骤的标准:
做完这一步,应该能明确知道「产生了什么结果」,并且知道「怎么判断它完成了」。
五、组装本身也是验证
单测都通过不代表组装正确。每向上一层,会发现一种新问题:
1 | 接口不匹配 |
所以验证是分层的:
1 | 单元验证 → 组件验证 → 子系统验证 → 系统集成验证 → 整体验证 |
组装 = 把多个已验证的小闭环拼成更大的闭环,再验证一次。 每上一层都发现新问题,这就是闭环半径扩大时必然的检查点。
六、编程学习 = 一个个可编码执行验证的最小闭环
学习编程和软件开发是同一个模式——学习 = 一个个可以不断编码、执行、验证的最小闭环:
1 | 写一小段代码(输入+处理+输出) |
1 | 学一个语法: |
真正的学习不是「把模型装进脑子里」,而是从具体世界建立模型,再拿模型回到具体世界验证。 读语法书不是学习,读 + 写 + 运行 + 验证才是——因为后者形成了闭环。
学习里的「验证」对应:
1 | 写代码 → 编译错误(验证失败 → 修改)→ 运行结果(验证 → 和预期比) |
编程学习的每一个小练习,都是一个最小闭环:写 → 跑 → 看 → 改。 这一圈圈闭环积累起来,就是掌握一门语言的过程。
七、三种工程模式的本质都是闭环
传统工程有三种模式,本质都是「闭环半径的扩大方式」不同:
1 | ① 经典工程:自顶向下设计 + 自底向上实现 |
共同点:每一步都是「实现一小块 → 验证 → 再扩大」的闭环。 差别只在设计是显式还是隐式。
八、和其他线的关系
1 | 本线 ←→ 设计表示(06-设计/03) |
收束
1 | 软件开发的错误流程:设计 → 全部写完 → 最后一次运行(失败) |
软件开发 = 自顶向下设计 + 自底向上实现 + 步步可验证的闭环。 编程学习 = 一个个能写能跑能验证的小闭环。两者是同一个东西。
