从“我想做个应用”到一份能执行的设计
读解释、检查证据、修订自己的设计。正文与参考记录可离线阅读,真实网络观察需要联网或启动本机服务。
导出包含第 0–7 章作答。导入会替换八章全部作答,包括文件中未包含的章节;建议先导出备份。
先修:知道请求、响应和状态的位置 · 本章无需安装
2.1 先写承诺,再画系统
小林想做一个私人笔记工具:“手机能记,电脑能看,最好简单一点。”这句话还不能指导实现。手机离线写完后是否自动上传?电脑已经打开的旧页面要不要立刻变化?两边同时修改时,谁的内容留下?若这些问题没有答案,同一张架构图可以被理解为完全不同的产品。
系统设计从这里开始:把使用场景变成可以检查的承诺,再安排由哪个程序、哪份数据实现它。图中的方框只是表达工具。你真正要交付的是一组相互一致的决定,包括做什么、暂不做什么、需要什么证据,以及什么时候重新考虑。
本章产物是一页设计底稿:明确需求、两个可行候选、一条选择及其代价。后续章节逐步补数据、接口、权限和失败路径。这是拟建应用的目标,不代表第一章的小演示已经具备全部功能。
2.2 把“能用”写成一个人可以验收的句子
先固定第一版:小林一个人使用,同一账号在手机、电脑上先后联网操作。手机收到保存成功后,电脑重新打开或刷新列表,应能读取刚提交的内容。已有页面不要求自动跳动;离线自动同步、实时协作和图片附件暂不支持。联网失败时要保留草稿并明确提示,不能把没保存的内容当成已保存。
“先后使用”能简化设计,但不能保证现实中永远没有旧页面。第一版仍需避免旧页面静默覆盖新修改;具体处理放在第三章。范围排除的是复杂协作体验,不是忽略可能发生的错误。
| 承诺 | 如何检查 |
|---|---|
| 创建、查看、修改、删除文字笔记 | 依次完成四步,每步重新读取,核对内容与对象编号 |
| 两设备联网后读取同一份已提交数据 | 手机保存取得确认,再从电脑刷新;比较同一笔记内容 |
| 只有本人能够读写私人笔记 | 用未登录及另一个测试身份直接请求,确认拒绝且数据不变 |
| 能带走自己的数据 | 导出一组已知笔记,在独立检查中核对数量、标题和正文 |
再给约束一个可修改的起点:预计两千条笔记,每条平均两 KiB,纯正文约四 MiB;这里没有算索引、附件、历史版本和备份。先把月支出上限设为五十元、日常维护投入设为每月两小时。它们是小林的预算要求,不能当成任何平台的实际报价或保证;选服务时还要逐项核实。
2.3 让每个方框承担具体责任
两台设备要取得同一份最新数据,先为本例选择一个共同的数据来源:通过联网服务访问的一份笔记记录。浏览器负责呈现、收集输入和反馈;接收请求的一方验证身份与输入、执行保存规则;存储保留已提交的内容。按钮禁用和页面隐藏只能改善体验,规则还必须在接收请求的一方执行。
在此基础上比较两种候选。A 是自己编写业务 API,再连接数据库。API 就是浏览器与应用约定的调用入口。你控制它怎样创建笔记、判断所有者和返回错误;应用和数据库都可以交给平台托管,不必自己购买或管理物理机器。
B 是浏览器调用托管身份与数据服务,由服务执行配置的访问规则。你少写一部分后端代码,但仍要定义谁能访问哪条记录、什么数据可写、怎样导出和恢复。这里调用的是受规则保护的服务接口;不是把具有任意读写权限的数据库凭据放进网页。
两张图表达的是责任分配,不是机器数量,也不是部署完成的证明。借鉴 C4 的应用与数据存储视图,每条箭头应能回答“谁向谁要什么”。读者无需先认识某个云产品,便能指出遗漏的保存路径。
2.4 比较同一组要求,承认尚未知道的成本
候选成立的前提是能满足同一组承诺。若某个托管服务无法表达我们的所有权规则,B 在该产品上就暂不合格;若自己没有时间实现并验证这些规则,A 也不能靠一张完整的图自动合格。对能力尚未确认的项目填写“待验证”,比打一个漂亮的总分更有用。
| 比较项 | A:自写业务 API | B:托管数据服务 | 选择前的证据 |
|---|---|---|---|
| 规则表达 | 能在自己的代码中组织规则,也要自己测试 | 受平台规则语言和接口能力约束 | 实现同一保存与拒绝用例 |
| 维护责任 | 应用更新、配置、故障定位;数据库可托管 | 平台承担部分运行工作,你仍维护客户端和规则 | 列出每项工作由谁做、多久做一次 |
| 费用 | 应用、数据库、备份与可能的网络支出 | 身份、存储、读写次数、网络等计费项 | 按同一用量查额度和超额价格;未知不填零 |
| 迁移 | 需搬数据和应用配置 | 还需核实数据、身份和规则能否迁出 | 导出样本并尝试读取,不只看宣传页 |
2.5 写一个可以被事实改变的决定
小林的完整决定可以这样写:“我暂选 A,因为本项目同时用于学习请求处理和数据规则。我接受需要维护业务代码,先用一条笔记的创建、读取和拒绝访问流程验证可行性。数据库是否托管另行决定。若实际维护持续超过每月两小时,并且 B 能通过同样的权限、导出和保存检查,再比较迁移投入。”
这里的“暂选”不是含糊:目标、理由、承担的代价、下一步证据和改选条件都已写清。若小林最看重快速完成现成规则覆盖的功能,暂选 B 也可以合格。课程后续用 A 解释处理链路;你仍可把相同的规则交给经过验证的托管能力执行。
再看一个坏决定:“先用本地存储,以后用户多了就改成微服务。”它既没有满足当前自动同步要求,也没有说明用户增多造成了哪个瓶颈。更有用的触发条件是“在给定数据量与网络条件下,反复测得读取等待超过约定目标”,随后查慢在何处。新组件应回答一个具体问题。
提示一:先排除不满足需求的候选
找出“另一设备刷新可见”和“未授权不可见”两条承诺。分别沿图追踪数据与检查位置,遗漏一条就不能只用价格给方案加分。
提示二:给不确定项安排一个小验证
不知道规则能否表达,就实现一次允许和一次拒绝;不知道迁移是否容易,就导出少量记录再读取。把“应该没问题”换成一个有输出的动作。
提示三:不同选择也可能都合格
A 可以以业务控制和学习为理由,B 可以以低维护为理由。合格答案都需通过共同的硬要求,并承认未验证部分。不能用“我喜欢”替代证据,也不用为选到教材同一个方案而修改需求。
2.6 换成离线旅行清单,重新做一次决定
现在把场景改成山区旅行:手机常常没有网络,只在每晚有网时把清单交给电脑,允许手动操作。只改这两条要求,哪些决定会变化?本地优先保存加导出/导入成为可行候选;而离线编辑的冲突、文件丢失和导入覆盖仍需说明。不要把“支持离线”写成一个没有数据路径的勾选项。
若第一项不清楚,回到 2.2;若比较仍是产品名称,回到 2.3–2.4。保留这份底稿,下一章把“数据库”展开成数据与约束。
精准选读与阅读问题
- C4 · System context diagram:读开头与 Supporting elements,检查你是否区分了使用者、自己的系统与外部服务。
- C4 · Container diagram:读开头和 Notes。应用/存储的责任图为什么不能代替部署方案?这里的 container 不专指 Docker。
- MIT 6.033 · Syllabus:只读 Learning Objectives 中关于论证和批评设计的段落。借鉴的是判断方式,不要求完成其大学课程先修。