跳转至

原型

它的作用

prototype 编写用于回答问题的临时代码:这个状态模型感觉是否合理,或者这个屏幕应该长什么样。问题优先,并决定你要构建什么。一个回答了错误问题的原型,无论看起来多好,都是浪费。

“临时”是对代码编写方式的约束,而不是承诺要销毁它。没有测试,没有超出运行所需的错误处理,没有抽象,没有持久化,因为这些都不能帮助你学会你试图学会的那一件事。有两样东西会保留下来。答案会进入真实代码,而原型会放到 main 之外的一个分支上,作为答案的证据。

何时使用

输入 /prototype,或者 代理 在任务符合时会自动使用它。

当你遇到一个无法靠讨论解决的问题时,就使用它:一个你无法在脑中把握边界情况的状态机,一个你无法想象直到看到三个版本并排比较的屏幕。拷问 会话在这些问题上会变得很长。代理重新表述,你猜测,范围不断扩大。停止拷问,构建临时版本,查看它,然后用一行文字回答。如果相反,已经构建的东西行为异常,而你想知道原因,请使用 diagnosing-bugs;原型探索要构建什么,而不是已构建的东西为什么坏了。

你也会在没有选择的情况下来到这里。wayfinder 会在其地图上提交 prototype 决策 工单,而你用这个技能处理其中一个。

两种分支

问题选择分支,而分支会产生不同的产物:

  • “这个逻辑 / 状态模型感觉是否合理?”:一个可共享的单个 HTML 文件。一个自包含页面,无需构建也无需服务器,某人双击即可打开。它带有一个带标签的状态面板,在每次点击后重新渲染,有自由操作按钮以便按任意顺序戳弄模型,以及带标签页的引导式演练(每个标签页一个场景,下面有要按的顺序按钮)。所有东西都用领域语言标注,因此你可以把它交给设计师、PM 或领域专家,让他们自己尝试模型。页面背后的逻辑是一个小型纯模块(一个 reducer、一个状态机、一组函数),其中没有 DOM 代码,因此你可以将验证过的版本直接移入真实代码。
  • “这应该长什么样?”:在一条路由上几个截然不同的 UI 变体,可从浮动底部栏和 ?variant= URL 参数切换。变体必须在结构上不一致,而不是颜色;三个带小改动的卡片网格回答不了任何问题。只要可能,它们就在真实页面内渲染,针对真实数据和真实密度,因为在空白页面上判断的变体总是看起来不错。

两者都在内存中保存状态,无需设置即可启动,并在每一步之后显示完整状态。一旦你发现自己正在加固其中一个(添加测试、连接真实数据库、为以后可能需要的情况做泛化),你就停止原型设计了。

原型是一手资料

一个完成的原型留下两样东西,它们去往不同地方。

你在某个永久地方记录答案(裁决加上它解决的问题):提交信息、ADR、实现 issue。main 保留答案,在真实代码中。

原型是答案来源的可运行证据,你不会删除它。它也不属于 main,因为没人维护它,而且很快会过时。因此你把它提交到 main 之外的一个临时 prototype/<name> 分支,永不合并,并在实现 issue 上留下指向该分支的 上下文指针。main 保持干净,下一个接手工作的人可以找到并重新运行原型。

常见问题

等等,原型不是应该被删除吗? 现在不是了。以前是:构建它,保留答案,扔掉代码。对那的最强反对不是关于速度。而是下一个 会话 由谁接手,以及他们有什么可以工作的基础? 原型的文字摘要会失去让它有说服力的东西。因此这个技能现在将原型视为 一手资料。它落在 main 之外的 prototype/<name> 分支上,实现 issue 指向它。改变的是代码存放的位置,而不是纪律;它仍然永不合并到 main。

它以前构建终端应用。那去哪了? 逻辑分支现在改为输出一个可共享的单个 HTML 文件。终端应用只能由克隆了仓库并安装了运行时的人驱动,这排除了原型需要其意见的人:设计师、PM、知道状态模型应该意味着什么的领域专家。一个自包含文件,双击即可打开,即使被邮件发送后仍然可用,任何人都可以驱动。下面的纯逻辑模块没有改变,仍然是你移入真实代码的部分。

代理告诉我应该 /prototype,而我本应该实现。 这是一个已知的命名问题。不知道流程的代理读到 prototype,一个通用而有吸引力的词,在工单存在时将其视为“明显的下一步”。因此即使设计已在对话中确定,代理也会按名称推荐它。如果你已经知道要构建什么,下一步是按工单执行 /implement。只有当某个具体设计问题未解决且讨论无法解决时,才使用原型。

我应该在构建任何生产功能之前先原型整个应用吗(比如说,为了向潜在客户演示)? 那是一个碰巧共享这个技能名称的不同产物。这里的一个原型限定于一个问题,而“整个应用是什么?”不是一个问题。整个应用的原型没有自然停止点,因此会漂移成生产应用:清理过程永远不会发生,在原型规则下编写的代码(没有测试、没有错误处理)最终出现在用户面前。如果你需要销售演示,请有目的地把它构建为演示,并明确说明其中没有任何生产代码。如果你需要确定一个设计问题,请把它缩小到那个问题。

我该如何在独立会话中运行它? 原型位于自己的目录中,并会生成大量你不想出现在提问线程中的上下文,因此请在其他地方运行它,并只把答案带回来。使用交接将工作移入该会话,并把答案带回来。

这难道不是烧 Token 最快的方式吗? 确实可能,如果你用原型去回答本可以通过对话解决的问题,或者让一个原型蔓延到整个功能。真正重要的比较不是 Token 对零,而是 Token 对构建错误的状态模型,并在它已有生产调用者之后才发现。保持问题狭窄、运行简短,花费就会保持相称。

如果它正在起作用

  • 你能用一句话说明原型存在要回答什么问题,并且它写在演示顶部,而不仅仅在你脑子里。
  • 不读代码的人也能驱动逻辑演示。他们打开文件,在演练选项卡中按下按钮,并用自己的话描述所见。
  • 有人说“等等,这不应该可能”或“咦,我以为 X”。这是想法中的 bug,而这正是原型的目的。
  • UI 变体在布局和层级上不一致,而不仅仅是颜色和文案,你得到的反馈是“B 的页眉加上 C 的侧边栏”。
  • 它能在一次会话中得到回答。如果你一天后还在构建它,说明问题太大;拆分它。
  • 结束后,main 包含决策,而不包含任何原型,并且实现 issue 指向仍持有它的分支。

它在哪里适用

prototype 是一个随时可取用的独立技能:你用它来敲定一个设计问题,然后回到你的工作。另一个技能也会运行它。

最常运行它的技能是wayfinder。wayfinder 地图由决策工单组成,而 prototype 是工单可采用的四种类型之一:当阻塞问题是“这应该看起来怎样”或“它应该如何表现”时使用,这些问题无论讨论多少都无法解决。当讨论含糊时,wayfinder 会制作一个具体可供反应的东西,而这个技能构建那个东西。答案解决一个原型工单,地图将原型作为资产链接起来。

其他相邻技能位于其上游和下游。grill-me 和 grill-with-docs 回答可拷问的问题;不可拷问的问题则来到这里,而一行答案会回到访谈中。下游,经过验证的状态模型或 UI 方向成为 to-spec 的既定输入,它可以内联原型产生的富含决策的片段,而不是用散文描述它。对于其他任何情况,ask-matt 会把你路由到整个技能集合。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 skills13/skills