Lec 20从需求到设计:独立开发者方法论
Lec 20 从需求到设计:独立开发者方法论
本学期最后一次课没有单独的讲义,而是 Project Fair:学生展示已经完成的项目。若只记录展会流程,这一讲会变成截止日期与交付物的清单;更有价值的读法,是从期末项目的检查点反推出课程完整的设计方法。
这套方法同样适合独立开发者。区别只在于:团队契约变成个人约束,导师例会变成固定复盘,分工计划变成时间与风险预算;需要回答的设计问题并没有减少。官方过程可参阅 Assignment 1: Problem Framing、Assignment 2: Functional Design 与 Final Project。
TL;DR
- 从需求到设计不是“先想功能,再画界面”,而是逐步消除四类不确定性:问题是否真实、方案是否有效、行为是否自洽、用户是否能够理解。
- Problem Framing 先用领域、问题、利益相关者、证据与对标方案建立需求证据链;功能在此阶段只是待验证的假设,不能反过来定义问题。
- Functional Design 用功能、概念与 Sync、用户故事/旅程、低保真 UI 草图和视觉设计从不同角度描述同一方案;这些产物必须能相互追溯,而不是各写各的。
- 独立开发者需要用设计日志、范围门槛、纵向切片和固定检查点代替团队流程;设计完成的标志不是稿子精致,而是核心旅程已闭环、关键风险有退路、下一步可以被验证。
设计的本质:逐步压缩不确定性
软件项目很少因为完全写不出代码而失败,更常见的情况是:做出了没人需要的东西、解决错了问题、功能彼此冲突,或者用户根本不知道怎么用。设计流程的作用,就是在实现成本还低时,按顺序暴露这些错误。
现实领域
↓ 发散与取证
问题框架(为什么值得解决)
↓ 选择价值主张与范围
功能设计(产品承诺什么)
├─ 用户故事 / 用户旅程:谁在什么情境下获得什么结果
├─ 概念与 Sync:系统以什么行为机制兑现承诺
├─ UI 草图:用户如何发现、执行并理解这些行为
└─ 视觉设计:信息如何形成层级、节奏与感受
↓ 一致性检查与范围裁剪
可验证的纵向切片
↓
原型、实现与用户测试,再回写设计
这不是一次性的瀑布流程。箭头表示当前最主要的推理方向,不表示前一步从此冻结。界面草图可能暴露缺少的状态,概念设计可能证明某个功能成本过高,用户测试也可能推翻最初的问题假设。
我的理解
设计不是提前写出所有答案,而是让错误尽可能早、尽可能便宜地出现。每份设计产物都应当对应一种尚未消除的不确定性;如果一份文档不会改变任何决策,它大概率只是文档表演。
阶段 0:先约束项目,而不是先扩大想象
团队项目用 Team Contract 管理协作风险。独立开发者没有沟通成本,却更容易同时扮演产品经理、设计师和工程师,在兴奋时不断加功能,在实现困难时偷偷改变问题。因此开始前应写一份很短的个人项目约束:
| 约束 | 要回答的问题 |
|---|---|
| 目标 | 这个项目主要验证需求、练习设计,还是交付可长期使用的产品? |
| 用户 | 第一批具体用户是谁?自己是否也是其中一员? |
| 时间预算 | 在什么日期前必须出现第一个可运行的核心旅程? |
| 技术边界 | 哪些技术已掌握,哪些依赖可能让项目失控? |
| 成功标准 | 用户完成什么行为,才说明产品开始产生价值? |
| 停止条件 | 出现什么证据时,应缩小范围、换方案或停止项目? |
这份约束不是宏大的愿景宣言,而是后续取舍的裁判。没有时间、用户和停止条件,“保持灵活”通常只是拒绝做决定。
阶段 1:Problem Framing——证明问题值得解决
Problem Framing 的输出不是产品方案,而是一条可以被反驳的需求主张:某类人在某个具体情境中,反复遇到某种可观察的困难;现有替代方案没有以足够低的成本解决它。
1.1 从熟悉领域发散,不从技术发散
先列出自己真正接触过的活动领域,再列出其中的困难。例如“学习公开课”是领域,“学完一讲后不知道下一步该读什么”才是问题;“做一个知识图谱”已经是方案。
发散时允许数量多、质量参差;收敛时再按以下条件筛选:
- 问题是否由用户体验,而不是由开发者想象?
- 困难是否重复发生,并带来时间、金钱、风险或情绪成本?
- 自己是否拥有领域接触、观察机会或独特洞察?
- 软件是否能改变结果,还是问题主要依赖政策、组织或线下资源?
- 在当前时间与能力范围内,能否交付一个完整而非玩具式的解法?
1.2 把问题和方案彻底分开
一个简单测试是暂时删掉产品名、技术名和功能名。如果剩下的句子仍描述了用户的困难,问题才可能成立。
| 表述 | 判断 |
|---|---|
| “现有课程网站没有 AI 推荐。” | 这是某种方案缺失,不是用户问题。 |
| “学习者完成一篇笔记后,无法判断后续内容的依赖关系,因此经常中断学习。” | 描述了人、情境、困难与后果,可以继续取证。 |
| “我要做一个更现代的课程网站。” | 这是设计偏好,没有证明需求。 |
常见误区
Solution-first(方案先行)最危险的地方不是太早想到好点子,而是之后所有研究都会被用来证明这个点子。允许自己先有灵感,但必须把灵感降级为“候选假设”,再独立验证问题。
1.3 建立需求证据链
一个可用的问题框架至少包含五部分:
- Domain:用户正在进行什么活动,自己为何理解这个领域。
- Problem:谁在什么情境下遇到什么困难,产生什么后果。
- Stakeholders:不仅列直接用户,也列会承担成本、风险或权力变化的人。
- Evidence:访谈、观察、行为记录、公开讨论、数据或研究,分别支持问题的存在、频率与强度。
- Comparables:用户现在如何应对,包括竞品、手工流程、表格、聊天群以及“干脆不做”。
对标研究不是整理竞品功能表,而是理解用户为什么仍不采用现有方案。若一个成熟产品已经低摩擦地解决问题,就不必凭“界面可以更漂亮”假设仍有机会。
与此同时,应提前做价值敏感分析:谁会获益、谁会受损、谁掌握数据和规则、产品成功后是否产生新的排斥、依赖、隐私或滥用风险。详见 Lec 18 价值敏感设计。
1.4 写出可证伪的问题简报
问题框架收敛后,可以压缩成一页简报:
## 领域
目标人群正在进行的活动,以及我与该领域的关系。
## 问题主张
谁,在什么情境下,遇到什么可观察的困难,产生什么后果。
## 证据与反证
- 支持问题存在的证据:……
- 降低问题重要性的证据:……
- 仍未确认的假设:……
## 现有替代方案
用户目前怎么做;为什么仍有缺口。
## 利益相关者与风险
直接用户、间接受影响者、潜在伤害。
## 成功信号
什么行为变化说明问题得到缓解,而不只是有人点击或注册。
进入功能设计前,至少应满足以下门槛:问题独立于具体方案成立;有来自目标用户或真实行为的证据;能说出用户当前的替代方案;知道最危险的反证是什么;并能定义一种可观察的改善。
阶段 2:Functional Design——把需求变成行为承诺
功能设计不是“列功能”。它要回答:产品准备向用户承诺什么行为,这些行为如何共同缓解已经验证的问题,以及用户能否在完整旅程中获得结果。
课程的 Functional Design 包含问题框架修订、功能、概念与 Sync、用户旅程、UI 草图、视觉设计研究和设计总结。它们不是从宏观到细节的重复描述,而是几种互相制约的模型。
2.1 先写价值假设,再决定功能范围
每个候选功能都应写成一条因果假设:
对于 某类用户,在 某个情境 下,提供 某种能力,会减少 已被证实的困难;我们将通过 可观察行为或结果 判断它是否有效。
优先级不应由“实现起来很酷”决定,而应看四个维度:
| 维度 | 关键问题 |
|---|---|
| 价值 | 没有这个功能,核心问题还解决得了吗? |
| 证据 | 哪条需求证据支持它? |
| 依赖 | 它是否要求尚不存在的数据、用户规模或外部服务? |
| 成本与风险 | 它最可能在哪个技术、交互或伦理假设上失败? |
第一版最好只保留一个主要价值主张和一条核心旅程。MVP 不是“每个功能都做一点”,而是最小但完整的用户结果。
2.2 用概念设计定义产品的行为骨架
功能是用户感知到的价值,概念(Concept) 是组成这些功能的独立行为单元。一个“到货时提醒我”的功能,可能由收藏、商品可用性、订阅与通知等多个概念共同完成;一个概念也可以服务多个功能。
每个概念用五个部分描述,详见 Lec 2 概念设计 与 Lec 3 行为设计:
| 部分 | 回答的问题 |
|---|---|
| Name | 用户会把这套行为理解成什么? |
| Purpose | 它独立存在是为了解决什么问题? |
| Operational Principle | 一个典型用户故事中,它如何兑现目的? |
| State | 为了维持承诺,系统必须记住什么? |
| Actions | 用户或系统可以发起哪些有意义的状态变化? |
然后用 Sync 声明不同概念如何协作:当某个动作发生,在满足什么条件时,触发哪个概念的动作。概念内部保持独立,组合关系显式写在 Sync 中,而不是让概念偷偷读写彼此状态。
检查概念时,不要只看名词是否齐全,而要追问:
- Purpose 能否独立成立,还是只是某个页面的局部需求?
- State 与 Actions 是否足以实现 Operational Principle?
- 两个动作交换顺序,结果是否仍合理?
- 失败、撤销、重复提交和权限变化时,承诺还能维持吗?
- 概念是否依赖另一个概念的内部细节?若是,边界可能画错了。
2.3 用户故事定边界,用户旅程验闭环
“用户故事”和“用户旅程”经常被混用,但承担的职责不同。
- 用户故事(User Story) 用一句话限定价值:作为某类用户,我希望完成某个目标,以便获得某种结果。
- 用户旅程(User Journey) 按时间讲述一个具体利益相关者如何遇到问题、决定采取行动、使用产品、处理反馈并得到结果。
一条可验证的旅程至少包含:
- 触发:用户为什么此刻需要行动?
- 进入:用户如何想起并找到产品?
- 核心步骤:为了得到价值,必须做哪些动作?
- 系统反馈:每一步如何让用户知道发生了什么?
- 异常与恢复:信息缺失、操作失败或改变主意时怎么办?
- 结果:用户的现实处境发生了什么变化?
- 后续:是否需要再次访问、协作、通知或数据维护?
旅程应从用户遇到问题开始,而不是从“打开 App”开始;也应在用户获得现实结果时结束,而不是停在“提交成功”。
2.4 UI 草图验证交互,不负责装饰
低保真 UI 草图把抽象行为变成可走查的屏幕、信息和动作。此时只需要表达:
- 页面或状态之间如何移动;
- 核心信息的层级和分组;
- 用户在每一步能看到什么、能做什么;
- 操作后出现什么反馈;
- 关键异常如何恢复。
草图应尽量单色、低成本、可快速丢弃。过早加入字体、配色和精致组件,会让人开始保护已经投入时间的稿子,反而不愿修改交互结构。可用 Lec 7 的用户旅程与线框图方法 做认知走查:用户是否知道下一步要做什么、能否发现正确动作、能否理解反馈、是否知道自己正在接近目标。
常见误区
“先把所有页面画出来”不是完整性。真正的完整性是:选一条核心旅程,逐步画出正常路径、空状态、等待、错误和恢复,并确认每个界面状态都能由概念状态解释。
2.5 视觉设计建立表达规则,不替代结构
当核心旅程和布局已经稳定,再做 Visual Design Study。它不是收集几张“喜欢的截图”,而是从参考中提炼可执行的规则:
- Layout:主要区域、阅读顺序、密度、留白与响应式关系;
- Typography:正文、标题、标签和操作文字如何建立层级;
- Color:颜色承担状态、强调、品牌或情绪中的哪种职责;
- Surface and imagery:边界、背景、图像与图标如何支持理解;
- Accessibility:对比度、字号、焦点、键盘与减少动态效果的要求。
每个参考都要写清“借鉴什么、为什么适合当前问题、不会照搬什么”。最终将这些判断收敛成少量设计 token 与组件规则。详见 Lec 14 视觉设计。
视觉设计不能修复错误的信息架构,也不能用精致感掩盖功能缺口。它的任务是让正确的结构更容易被理解,并使产品表达与使用情境一致。
阶段 3:让所有设计产物相互追溯
设计最常见的问题不是缺少文档,而是文档之间没有因果关系:证据支持问题 A,功能却解决 B;概念定义了 C,界面又绕过它直接实现 D。
可以维护一张轻量追溯表:
| 需求证据 | 问题/风险 | 成功信号 | 功能假设 | 概念与 Sync | 旅程步骤 | UI 状态 | 验证任务 |
|---|---|---|---|---|---|---|---|
| 哪条观察或资料? | 谁在何时受影响? | 什么现实结果改变? | 产品承诺什么? | 靠什么行为机制? | 用户如何获得价值? | 界面如何呈现? | 怎样证明成立? |
这张表不必为所有细节填满,但核心旅程应能从左走到右,也能从右反查到左。无法追溯的功能通常应被删除或降级;没有 UI 表达的概念动作可能无法被使用;没有概念状态支撑的 UI 状态可能只是静态幻觉。
假设性示例:课程笔记的“下一步阅读”
问题主张是“学习者读完一篇笔记后,不知道哪些内容是合理的下一步”,那么成功信号应是用户能基于可解释的依赖关系选择下一篇,而不是“推荐卡片点击率更高”。功能可能是下一步建议;概念可能包括内容依赖与阅读状态;用户旅程从完成当前内容开始;UI 必须说明推荐原因,并允许用户查看或修正路径。若仓库没有可靠的依赖数据,就应显示诚实的同课程上一篇/下一篇,而不是生成看似精确的前置关系。
阶段 4:把设计收敛为可验证的纵向切片
功能设计的最后产物不是一套静态稿,而是一份能指导下一轮验证的开发计划。计划应围绕纵向切片组织:每个切片贯穿必要的界面、行为、状态和数据,完成后可以真实演示一个用户结果。
4.1 选择第一个切片
第一个切片应同时满足:
- 直接触达核心问题,而不是先做通用设置页;
- 能由真实用户从头走到尾;
- 尽早触碰最危险的技术或数据依赖;
- 即使后续功能取消,它仍构成一个可理解的产品能力。
课程要求 Alpha 是可以演示的 MVP、Beta 接近完成,背后的方法不是按日期堆功能,而是尽早得到运行中的证据。对独立开发者而言,可以把它们改写成两道门槛:
| 检查点 | 要验证的事情 | 不应接受的替代品 |
|---|---|---|
| Alpha | 一条核心旅程端到端运行,最危险依赖已有答案 | 只有漂亮首页、孤立组件或假数据演示 |
| Beta | 主要状态、异常和恢复已覆盖,可交给目标用户独立操作 | 仍需开发者在旁解释或手动修数据 |
4.2 为风险预先写退路
开发计划至少记录三类风险:
- 价值风险:用户可能根本不在意,或现有替代已足够好;
- 可用性风险:用户可能不理解概念、找不到动作或不信任结果;
- 可行性风险:数据、API、模型效果、性能或时间预算可能不成立。
每项高风险都应有最早验证方式、判断日期和 fallback。Fallback 不是临近截止日期时砍掉一切,而是提前设计的较小但完整方案。
4.3 Design Ready 的退出条件
在开始大规模实现前,核心范围应满足:
- 问题与方案分开表达,并有真实证据和明确反证;
- 目标用户、利益相关者与潜在伤害已经识别;
- 每个核心功能都能追溯到问题与成功信号;
- 核心概念的 purpose、principle、state、actions 自洽;
- 关键 Sync 能解释跨概念行为,不依赖隐式耦合;
- 一条核心用户旅程从触发到现实结果完整闭环;
- 低保真草图覆盖正常、空、等待、错误和恢复状态;
- 视觉方向已形成规则,但没有锁死仍需验证的交互;
- 第一条纵向切片、主要风险与 fallback 已确定。
“Design Ready” 不等于设计冻结,而是现有假设已经清楚到足以接受实现和用户反馈的检验。
独立开发者的最小运行节奏
缺少团队并不意味着可以省掉反馈机制。更实际的做法,是把课程里的 Project Updates、Peer Critique 和 User Testing 缩成一个低成本循环。
持续维护设计日志
用一个 Markdown 文件记录:日期、观察、待验证假设、决策、理由、替代方案和结果。尤其记录“为什么删掉某功能”和“什么证据让设计改变”。这会防止几周后只记得结论,却忘记结论成立的条件。
每周做一次设计检查
每周固定回答五个问题:
- 本周获得了什么新证据?
- 哪个原有假设被加强、削弱或推翻?
- 设计发生了什么变化,为什么?
- 当前最大的价值、可用性和可行性风险分别是什么?
- 下周最小的可验证结果是什么?
在不同保真度下寻求反馈
- 问题阶段让目标用户讲真实经历,不向他们推销方案;
- 功能阶段让他人批评价值主张与范围;
- 草图阶段让用户完成任务,不解释界面;
- 视觉阶段让设计批评聚焦层级、可读性与表达规则;
- 原型阶段观察行为、停顿、误解和恢复,而不只问“你喜欢吗”。
用户测试方法详见 Lec 17 用户测试。关键原则是测试设计,而不是测试用户:用户卡住时,先记录系统提供了什么错误线索,不把失败归因于用户“不够懂”。
常见的错误顺序
| 错误做法 | 为什么危险 | 应回到哪里 |
|---|---|---|
| 先选技术,再寻找使用场景 | 技术能力会伪装成用户价值 | Problem Framing:重新找独立于技术的问题 |
| 先画高保真首页 | 投入感会掩盖核心旅程尚未成立 | 用户旅程与低保真草图 |
| 把竞品功能全部补齐 | 得到更重的克隆,而非更好的解法 | 证据、价值假设与范围裁剪 |
| 把数据库实体当概念 | 数据结构无法解释用户为什么需要它 | Purpose 与 Operational Principle |
| 用“作为用户,我想要更多功能”写用户故事 | 没有情境、动机和现实结果 | 具体利益相关者与用户旅程 |
| 在一张图中画完所有页面 | 看似完整,却无法验证端到端行为 | 一条核心旅程与纵向切片 |
| 用户测试只问喜不喜欢 | 礼貌意见不能代表真实行为 | 基于任务的观察与 Think Aloud |
| 直到完成后才考虑伦理 | 关键伤害可能已经写进概念与数据模型 | 利益相关者分析与价值敏感设计 |
一套可复用的最小方法
如果把整门课压缩成独立开发者每次都能执行的步骤,可以保留以下八步:
- 写约束:目标用户、时间预算、成功与停止条件。
- 找问题:从熟悉领域发散,再用真实性、价值与可行性收敛。
- 做取证:观察用户、收集反证、研究替代方案和利益相关者。
- 定承诺:只保留能改变核心结果的功能假设。
- 建行为模型:用概念、状态、动作与 Sync 解释产品如何工作。
- 走通旅程:从现实触发到现实结果,检查正常路径与异常恢复。
- 先画结构、后定视觉:低保真验证交互,高保真建立表达规则。
- 切出可验证版本:用纵向切片、风险测试和用户观察继续修正设计。
我的理解
这套方法真正的核心不是产物数量,而是两条纪律:每项功能都能向左追溯到真实问题,每个设计决策都能向右落到可观察的验证。 前者防止做出没有需求的产品,后者防止设计停留在无法证伪的叙述里。Project Fair 展示的是结果;从问题框架到每次设计变更的证据链,才是一个独立开发者能够反复迁移到下一项目的方法。