<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Happy-Path on Tarragon</title><link>https://tarrragon.github.io/blog/tags/happy-path/</link><description>Recent content in Happy-Path on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 19 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/happy-path/index.xml" rel="self" type="application/rss+xml"/><item><title>反模式：假設使用者只走 happy path</title><link>https://tarrragon.github.io/blog/ux-design/01-screen-state-machine/anti-pattern-happy-path-only/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/ux-design/01-screen-state-machine/anti-pattern-happy-path-only/</guid><description>&lt;p>假設使用者只走 happy path 是指 UI 設計只覆蓋「一切順利」的情境 — 連線成功後打字、配對成功後連線、操作完成後返回 — 而忽略使用者在非順利情境下的需求。非順利情境包括：等待中想取消、失敗後想換方向、成功後想離開、中途想做其他事。&lt;/p>
&lt;h2 id="隱性假設如何產生">隱性假設如何產生&lt;/h2>
&lt;p>開發者設計 connected 狀態時，注意力在「終端機介面的功能」— 打字、特殊鍵、滾動。「使用者可能想離開 connected 狀態回到首頁」這個需求在 happy path 中不存在 — 如果一切順利，使用者為什麼要離開？&lt;/p>
&lt;p>這個推論在使用者行為和開發者假設吻合時成立。但使用者可能想：&lt;/p>
&lt;ul>
&lt;li>切換到配對畫面重新配對另一台裝置&lt;/li>
&lt;li>暫時離開終端機處理其他事&lt;/li>
&lt;li>遇到回應異常想從頭重新連線&lt;/li>
&lt;li>覺得功能不符需求想回到首頁看其他選項&lt;/li>
&lt;/ul>
&lt;p>app_tunnel 的 Terminal 畫面五個狀態都沒有退出路徑。connected 狀態有打字和特殊鍵操作，但沒有「離開」操作；error 和 disconnected 有重連按鈕，但沒有「放棄重連、回首頁」的選項。開發者設計 error 狀態時的隱性假設是「使用者遇到錯誤會想重試」— 沒考慮「使用者可能想放棄」（&lt;a href="https://tarrragon.github.io/blog/ux-design/cases/five-states-zero-exits/" data-link-title="U.C1 Terminal 畫面五個狀態零個退出路徑" data-link-desc="Flutter app 的 Terminal 畫面有 idle/connecting/connected/error/disconnected 五個 enum 狀態，每個狀態都沒有 back 或 disconnect 按鈕 — 使用者一旦進入就出不去">U.C1&lt;/a>）。&lt;/p>
&lt;h2 id="happy-path-偏差的擴散">Happy path 偏差的擴散&lt;/h2>
&lt;p>Happy path 偏差不只發生在單一畫面。首頁只放 Connect Terminal 按鈕、沒放配對入口，是首頁層級的 happy path 偏差 — 假設使用者已經完成配對、只需要連線（&lt;a href="https://tarrragon.github.io/blog/ux-design/cases/missing-enrollment-entry-point/" data-link-title="U.C4 首頁缺配對入口按鈕、導航流未完整列出" data-link-desc="Flutter app 首頁只有 Connect Terminal 按鈕、沒有 Enroll Device 入口 — 使用者首次使用時找不到配對功能。根因是導航流設計只考慮了日常操作（UC-02 連線）、遺漏了首次操作（UC-01 配對）的入口">U.C4&lt;/a>）。&lt;/p>
&lt;p>操作盤點的「前端引導」只描述顯示不描述操作和退出，是設計流程層級的 happy path 偏差 — 關注「順利時使用者看到什麼」，忽略「不順利時使用者能做什麼」。&lt;/p>
&lt;p>從企劃到設計到實作，每一層的 happy path 偏差累積起來，最終產出的 app 在正常情境下運作良好，在任何偏離的情境下使用者都被困住。&lt;/p>
&lt;h2 id="用狀態矩陣防止">用狀態矩陣防止&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/ux-design/knowledge-cards/screen-state-matrix/" data-link-title="畫面狀態矩陣" data-link-desc="說明用四欄表格（顯示/可用操作/進入條件/退出路徑）系統性地暴露畫面導航缺口的設計工具">畫面狀態矩陣&lt;/a>的四欄結構（顯示 / 可用操作 / 進入條件 / 退出路徑）強制設計者回答每個狀態的操作和退出問題。不需要預測使用者的所有行為，只需要機械式地對每個狀態填寫四欄 — 空白格自動暴露缺口。&lt;/p>
&lt;p>具體的檢查規則：&lt;/p>
&lt;p>&lt;strong>退出路徑欄為空&lt;/strong>：需要補退出路徑。即使是 connecting 這種過渡狀態，使用者也應該能取消。&lt;/p>
&lt;p>&lt;strong>可用操作欄只有一個選項&lt;/strong>：使用者在這個狀態下只有一條路。如果這條路走不通（重連失敗），使用者被困住。至少考慮加一條替代路徑（返回、取消）。&lt;/p>
&lt;p>&lt;strong>進入條件是不可逆的&lt;/strong>：使用者無法自行觸發進入條件的反向操作（例如「連線成功」的反向操作「斷開連線」不存在）。這代表使用者進入後無法主動退出，只能等系統狀態變化。&lt;/p>
&lt;p>狀態矩陣的價值在於機械式的完整性檢查。填完所有狀態的四欄是一個 10 分鐘的工作（以 5 個狀態的畫面為例），產出是一張可以直接轉為 test case 的表格，同時能在實作前發現所有退出路徑缺口。&lt;/p>
&lt;p>矩陣的四欄定義和填寫步驟在&lt;a href="https://tarrragon.github.io/blog/ux-design/01-screen-state-machine/state-matrix-definition/" data-link-title="畫面狀態矩陣的定義與填寫方法" data-link-desc="四欄矩陣（顯示 / 可用操作 / 進入條件 / 退出路徑）的定義、填寫步驟和檢查規則 — 退出路徑為空 = UX 死胡同">畫面狀態矩陣的定義與填寫方法&lt;/a>中完整展開。如果畫面設計從 BDD 操作盤點出發，&lt;a href="https://tarrragon.github.io/blog/ux-design/01-screen-state-machine/bdd-to-state-matrix/" data-link-title="從 BDD 操作盤點展開到狀態矩陣" data-link-desc="五步驟把 BDD 操作盤點的「前端引導」展開成完整的畫面狀態矩陣 — 補上操作和退出這兩個容易遺漏的面向">從 BDD 操作盤點展開到狀態矩陣&lt;/a>提供五步驟的展開流程。填完的矩陣可以直接轉成 widget test case — 具體方法見 &lt;a href="https://tarrragon.github.io/blog/testing/04-ui-automation/" data-link-title="模組四：自動化 UI 驗證" data-link-desc="Widget test 的狀態覆蓋策略、Playwright 驗證流程、螢幕狀態 coverage">testing 模組四 UI 自動化&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>假設使用者只走 happy path 是指 UI 設計只覆蓋「一切順利」的情境 — 連線成功後打字、配對成功後連線、操作完成後返回 — 而忽略使用者在非順利情境下的需求。非順利情境包括：等待中想取消、失敗後想換方向、成功後想離開、中途想做其他事。</p>
<h2 id="隱性假設如何產生">隱性假設如何產生</h2>
<p>開發者設計 connected 狀態時，注意力在「終端機介面的功能」— 打字、特殊鍵、滾動。「使用者可能想離開 connected 狀態回到首頁」這個需求在 happy path 中不存在 — 如果一切順利，使用者為什麼要離開？</p>
<p>這個推論在使用者行為和開發者假設吻合時成立。但使用者可能想：</p>
<ul>
<li>切換到配對畫面重新配對另一台裝置</li>
<li>暫時離開終端機處理其他事</li>
<li>遇到回應異常想從頭重新連線</li>
<li>覺得功能不符需求想回到首頁看其他選項</li>
</ul>
<p>app_tunnel 的 Terminal 畫面五個狀態都沒有退出路徑。connected 狀態有打字和特殊鍵操作，但沒有「離開」操作；error 和 disconnected 有重連按鈕，但沒有「放棄重連、回首頁」的選項。開發者設計 error 狀態時的隱性假設是「使用者遇到錯誤會想重試」— 沒考慮「使用者可能想放棄」（<a href="/blog/ux-design/cases/five-states-zero-exits/" data-link-title="U.C1 Terminal 畫面五個狀態零個退出路徑" data-link-desc="Flutter app 的 Terminal 畫面有 idle/connecting/connected/error/disconnected 五個 enum 狀態，每個狀態都沒有 back 或 disconnect 按鈕 — 使用者一旦進入就出不去">U.C1</a>）。</p>
<h2 id="happy-path-偏差的擴散">Happy path 偏差的擴散</h2>
<p>Happy path 偏差不只發生在單一畫面。首頁只放 Connect Terminal 按鈕、沒放配對入口，是首頁層級的 happy path 偏差 — 假設使用者已經完成配對、只需要連線（<a href="/blog/ux-design/cases/missing-enrollment-entry-point/" data-link-title="U.C4 首頁缺配對入口按鈕、導航流未完整列出" data-link-desc="Flutter app 首頁只有 Connect Terminal 按鈕、沒有 Enroll Device 入口 — 使用者首次使用時找不到配對功能。根因是導航流設計只考慮了日常操作（UC-02 連線）、遺漏了首次操作（UC-01 配對）的入口">U.C4</a>）。</p>
<p>操作盤點的「前端引導」只描述顯示不描述操作和退出，是設計流程層級的 happy path 偏差 — 關注「順利時使用者看到什麼」，忽略「不順利時使用者能做什麼」。</p>
<p>從企劃到設計到實作，每一層的 happy path 偏差累積起來，最終產出的 app 在正常情境下運作良好，在任何偏離的情境下使用者都被困住。</p>
<h2 id="用狀態矩陣防止">用狀態矩陣防止</h2>
<p><a href="/blog/ux-design/knowledge-cards/screen-state-matrix/" data-link-title="畫面狀態矩陣" data-link-desc="說明用四欄表格（顯示/可用操作/進入條件/退出路徑）系統性地暴露畫面導航缺口的設計工具">畫面狀態矩陣</a>的四欄結構（顯示 / 可用操作 / 進入條件 / 退出路徑）強制設計者回答每個狀態的操作和退出問題。不需要預測使用者的所有行為，只需要機械式地對每個狀態填寫四欄 — 空白格自動暴露缺口。</p>
<p>具體的檢查規則：</p>
<p><strong>退出路徑欄為空</strong>：需要補退出路徑。即使是 connecting 這種過渡狀態，使用者也應該能取消。</p>
<p><strong>可用操作欄只有一個選項</strong>：使用者在這個狀態下只有一條路。如果這條路走不通（重連失敗），使用者被困住。至少考慮加一條替代路徑（返回、取消）。</p>
<p><strong>進入條件是不可逆的</strong>：使用者無法自行觸發進入條件的反向操作（例如「連線成功」的反向操作「斷開連線」不存在）。這代表使用者進入後無法主動退出，只能等系統狀態變化。</p>
<p>狀態矩陣的價值在於機械式的完整性檢查。填完所有狀態的四欄是一個 10 分鐘的工作（以 5 個狀態的畫面為例），產出是一張可以直接轉為 test case 的表格，同時能在實作前發現所有退出路徑缺口。</p>
<p>矩陣的四欄定義和填寫步驟在<a href="/blog/ux-design/01-screen-state-machine/state-matrix-definition/" data-link-title="畫面狀態矩陣的定義與填寫方法" data-link-desc="四欄矩陣（顯示 / 可用操作 / 進入條件 / 退出路徑）的定義、填寫步驟和檢查規則 — 退出路徑為空 = UX 死胡同">畫面狀態矩陣的定義與填寫方法</a>中完整展開。如果畫面設計從 BDD 操作盤點出發，<a href="/blog/ux-design/01-screen-state-machine/bdd-to-state-matrix/" data-link-title="從 BDD 操作盤點展開到狀態矩陣" data-link-desc="五步驟把 BDD 操作盤點的「前端引導」展開成完整的畫面狀態矩陣 — 補上操作和退出這兩個容易遺漏的面向">從 BDD 操作盤點展開到狀態矩陣</a>提供五步驟的展開流程。填完的矩陣可以直接轉成 widget test case — 具體方法見 <a href="/blog/testing/04-ui-automation/" data-link-title="模組四：自動化 UI 驗證" data-link-desc="Widget test 的狀態覆蓋策略、Playwright 驗證流程、螢幕狀態 coverage">testing 模組四 UI 自動化</a>。</p>
]]></content:encoded></item></channel></rss>