cover

好產品的定義與特徵

流程概覽

flowchart LR
    A[問題定義<br/>Problem] --> B[使用者研究<br/>User Research]
    B --> C[功能優先排序<br/>Prioritization]
    C --> D[產品需求文件<br/>PRD]
    D --> E[MVP 驗證<br/>Validation]
    E -->|回饋迭代| B

    style A fill:#F44336,color:#fff
    style B fill:#2196F3,color:#fff
    style C fill:#FF9800,color:#fff
    style D fill:#4CAF50,color:#fff
    style E fill:#9C27B0,color:#fff

文章概覽

在本篇文章中,您將學習到:

  • 為什麼「好專案」不等於「好產品」,以及這個區別對工程師為什麼重要
  • 好產品的五大維度:使用者體驗、技術品質、可維護性、商業價值、團隊與流程
  • 每個維度的具體衡量標準與實務案例
  • 產品在不同生命週期階段,「品質」的定義如何變化
  • 技術指標、業務指標與開發者體驗指標的完整框架
  • 四種常見的反模式,以及如何避免
  • 在品質與速度之間取得平衡的實務建議

引言:什麼才是「好產品」?

如果你問十個工程師「什麼是好產品」,你可能會得到十個不同的答案:

  • 「程式碼乾淨、架構漂亮」
  • 「測試覆蓋率 90% 以上」
  • 「效能好、延遲低」
  • 「CI/CD 流程完善、部署頻繁」

如果你問十個 PM,答案又會不同:

  • 「用戶喜歡用」
  • 「DAU 持續成長」
  • 「客戶願意付費」
  • 「市場佔有率領先」

如果你問十個使用者,答案更直覺:

  • 「好用」
  • 「不會當」
  • 「快」
  • 「能解決我的問題」

這些答案都對,但都不完整。好產品不是單一維度的極致,而是多個維度之間的動態平衡。 一個技術架構完美但沒人用的專案不是好產品;一個用戶百萬但隨時可能崩潰的系統也不是好產品;一個功能強大但新人需要三個月才能上手維護的程式碼庫,同樣不是好產品。

本文將從工程師的視角出發,建立一套完整的框架來定義和衡量「好產品」。這不只是學術討論——當你能夠清楚地定義品質,你就能在日常決策中做出更好的 trade-off:什麼時候該追求完美,什麼時候「夠好就好」,什麼時候該償還技術債,什麼時候該先 ship。


好產品 vs 好專案

在展開好產品的五大維度之前,我們需要先釐清一個根本性的區別:好專案(Good Project)和好產品(Good Product)是兩件完全不同的事情。

好專案的定義

在傳統的專案管理框架中,一個好專案通常由以下指標定義:

指標定義衡量方式
如期交付在約定的時間內完成實際完成日期 vs 計畫日期
預算內不超過預算實際花費 vs 預算
範圍符合交付了約定的功能需求清單的完成率
利害關係人滿意客戶/老闆覺得滿意驗收結果

一個專案如果在時間、預算、範圍三個約束條件內完成,並且通過驗收,在專案管理的角度就是「成功」的。

好產品的定義

但從產品的角度來看,專案管理的成功指標是遠遠不夠的。一個產品的品質,取決於使用者實際使用時的體驗,以及它在市場上的長期生存能力

考慮以下場景:

場景一:好專案,壞產品

一個外包團隊在三個月內如期交付了一個 CRM 系統,功能完全符合需求文件,預算也沒有超支。專案被視為成功結案。然而上線三個月後,客服部門的員工抱怨系統太慢、操作邏輯不直覺、頻繁出錯。半年後,公司決定換掉這個系統。

這個專案是成功的(如期、如預算、如範圍),但產品是失敗的(使用者不想用、無法持續提供價值)。

場景二:壞專案,好產品

一個新創團隊開發一個協作工具,原定三個月完成 MVP,結果花了八個月。期間改了三次技術架構、重寫了兩次核心模組、超支 200%。從專案管理的角度看,這是一場災難。但最終產品上線後,用戶留存率 60%,口碑傳播帶來穩定增長,一年後獲得 B 輪融資。

這個專案是失敗的(嚴重延期、嚴重超支),但產品是成功的(用戶喜歡、有商業價值)。

這個區別為什麼重要?

對工程師而言,這個區別至關重要,因為它影響了我們在日常工作中如何做決策:

  1. 最佳化目標不同:如果你最佳化的是「專案指標」,你會傾向於趕工、砍功能、跳過測試、累積技術債——只要能在 deadline 前交付就好。如果你最佳化的是「產品品質」,你會更願意在前期投入時間做架構設計、寫測試、優化 UX。

  2. 評估時間軸不同:專案是有限期的(kick-off → delivery),但產品是持續的(launch → iterate → sunset)。一個在交付時刻看起來完美的專案,可能在上線六個月後變成維護地獄。

  3. 責任範圍不同:專案交付後通常就結案了,但產品需要持續維護、迭代、改進。工程師如果只關注專案交付,會忽略長期可維護性、技術債、知識傳承等關鍵因素。

核心觀點:工程師應該用「產品思維」來做技術決策,而不是只用「專案思維」。 這意味著在寫每一行程式碼時,不只考慮「能不能在 deadline 前完成」,還要考慮「六個月後這段程式碼還好不好維護」、「使用者用起來是否順暢」、「系統能不能 scale」。


好產品的五個維度

好產品的品質可以從五個維度來衡量。這五個維度不是獨立的,而是相互關聯、相互影響的。

                    ┌──────────────────┐
                    │   使用者體驗      │
                    │ User Experience  │
                    └────────┬─────────┘
                             │
              ┌──────────────┼──────────────┐
              │              │              │
    ┌─────────▼──────┐       │    ┌─────────▼──────┐
    │   技術品質      │       │    │   商業價值      │
    │ Tech Quality   │       │    │ Business Value │
    └─────────┬──────┘       │    └─────────┬──────┘
              │              │              │
              └──────────────┼──────────────┘
                             │
              ┌──────────────┼──────────────┐
              │              │              │
    ┌─────────▼──────┐       │    ┌─────────▼──────┐
    │   可維護性      │       │    │  團隊與流程     │
    │ Maintainability│       │    │ Team & Process │
    └────────────────┘       │    └────────────────┘
                             │
                     ┌───────▼───────┐
                     │   好產品       │
                     │ Good Product  │
                     └───────────────┘

1. 使用者體驗(User Experience)

使用者體驗是好產品最外層、也是最容易被使用者感知的維度。不管你的程式碼多優雅、架構多漂亮,使用者看到的只有介面和互動。

直覺性(Intuitiveness)

定義: 使用者不需要閱讀說明書,就能理解如何使用你的產品。

直覺性的核心在於「符合使用者的心智模型(Mental Model)」。使用者在使用你的產品之前,已經有了一套基於過去經驗建立的操作預期。好的產品會順應這些預期,而不是強迫使用者學習新的操作模式。

好的例子:

  • 拖曳檔案到垃圾桶圖示來刪除檔案——符合實體世界的隱喻
  • 點擊表格的欄位標題來排序——已經是普遍的 UI 慣例
  • Ctrl+Z / Cmd+Z 來復原——跨應用程式的通用快捷鍵

壞的例子:

  • 需要先「解鎖」才能「編輯」——增加了不必要的操作步驟
  • 刪除按鈕放在「新增」按鈕旁邊,而且沒有確認對話框
  • 儲存功能藏在三層選單裡,而且沒有自動儲存

工程師常犯的直覺性錯誤:

工程師設計 UI 時,常常以「技術架構」而非「使用者任務」來組織功能。例如,把設定項目按照「後端 module 分類」而非「使用者的使用情境」來歸類。使用者不在乎你的後端有幾個 microservice,他們只在乎「我要怎麼完成我的任務」。

一致性(Consistency)

定義: 產品內部的操作邏輯、視覺風格、用詞應該保持統一。

一致性降低了使用者的認知負擔。當使用者在 A 頁面學會了某個操作方式,他們會期待在 B 頁面也能用同樣的方式操作。

面向一致不一致
互動模式所有列表都用同樣的方式分頁、排序、篩選有些列表用分頁,有些用無限捲動,有些要點「更多」按鈕
視覺風格主要操作永遠是藍色按鈕,危險操作永遠是紅色按鈕有時候紅色表示「重要」,有時候表示「危險」
用詞全部用「儲存」,或全部用「提交」有些地方叫「儲存」,有些叫「確認」,有些叫「送出」
錯誤訊息統一格式:描述問題 + 建議解法有些顯示技術錯誤代碼,有些顯示友善訊息,有些什麼都不顯示
快捷鍵刪除在任何地方都是 Delete有些用 Delete,有些用 Backspace,有些沒有快捷鍵
回饋感(Feedback)

定義: 每一個使用者操作都應該有明確的回饋,讓使用者知道「系統收到了」。

人類對「無回應」的容忍度極低。當你按下一個按鈕,如果什麼都沒發生,你的第一反應是「是不是沒按到?」然後再按一次。如果那個按鈕觸發的是「購買」或「刪除」操作,二次點擊可能造成嚴重問題。

回饋的三個層次:

  1. 即時回饋(< 100ms):按鈕的按壓效果、hover 狀態變化、輸入框的 focus 狀態。這些回饋應該是瞬間的,讓使用者知道「我的操作被接收了」。

  2. 進度回饋(100ms - 10s):Loading spinner、進度條、skeleton screen。當操作需要等待時,使用者需要知道「系統正在處理」。

  3. 結果回饋(操作完成後):成功通知(Toast / Snackbar)、錯誤訊息、狀態更新。使用者需要知道「操作的結果是什麼」。

常見的回饋缺失模式:

// 壞的做法:按鈕沒有 loading 狀態
<button onClick={handleSubmit}>提交</button>

// 好的做法:按鈕在提交時顯示 loading 狀態並禁用
<button
  onClick={handleSubmit}
  disabled={isLoading}
>
  {isLoading ? '提交中...' : '提交'}
</button>
// 壞的做法:API 呼叫失敗但使用者不知道
try {
  await api.updateUser(data);
} catch (error) {
  console.error(error); // 只有開發者看得到
}

// 好的做法:API 呼叫失敗時通知使用者
try {
  await api.updateUser(data);
  toast.success('個人資料已更新');
} catch (error) {
  toast.error('更新失敗,請稍後再試');
  logger.error('Failed to update user', { error, data });
}
容錯性(Error Tolerance)

定義: 使用者犯錯時,系統應該提供復原的途徑,而不是讓錯誤變成不可逆的災難。

容錯性的設計原則:

  1. 預防錯誤:透過 UI 設計減少犯錯的可能性

    • 用 dropdown 取代自由輸入(限制可選範圍)
    • 用日期選擇器取代手動輸入日期格式
    • 在危險操作前顯示確認對話框
  2. 偵測錯誤:即時驗證使用者的輸入

    • 即時表單驗證(不要等到送出才告訴使用者哪裡錯了)
    • 格式檢查與提示(例如:「密碼需要包含大小寫字母和數字」)
  3. 復原錯誤:提供 undo/redo 機制

    • Gmail 的「撤銷傳送」——在 30 秒內可以撤回已發送的郵件
    • Google Docs 的版本歷史——可以回到任何一個歷史版本
    • 資料庫的 soft delete——刪除不是真的刪除,而是標記為「已刪除」

一個好的容錯設計案例:

想像一個檔案管理系統。使用者不小心刪除了一個重要檔案。

容錯等級行為使用者體驗
無容錯檔案立即被永久刪除使用者崩潰
基本容錯刪除前需要確認「確定要刪除嗎?」使用者可能已經養成「無腦點確認」的習慣
良好容錯刪除後放入垃圾桶,30 天後自動清除使用者可以在 30 天內復原
優秀容錯刪除後顯示 Toast「檔案已刪除」+ Undo 按鈕使用者可以在幾秒內一鍵復原

2. 技術品質(Technical Quality)

技術品質是使用者通常看不見,但會深刻影響使用者體驗的維度。一個「看起來能用」和「真正好用」的產品,差距往往就在技術品質上。

效能(Performance)

效能直接影響使用者體驗。研究顯示:

  • 100ms 以內:使用者感覺是「即時」的
  • 100ms - 1s:使用者感覺「有一點延遲,但可接受」
  • 1s - 10s:使用者會失去對操作的流暢感,需要進度指示
  • 超過 10s:使用者會離開
指標「看起來能用」「真正好用」
首次載入時間(FCP)< 5s< 1.5s
最大內容繪製(LCP)< 4s< 2.5s
首次輸入延遲(FID)< 300ms< 100ms
累積版面位移(CLS)< 0.25< 0.1
API 回應時間(P95)< 3s< 500ms
API 回應時間(P99)< 10s< 1s
記憶體使用能跑就好有 profiling、有 leak 偵測
資料庫查詢沒有 N+1,沒有 full table scan有 query plan review、有索引策略
可靠性(Reliability)

可靠性衡量的是系統在各種條件下持續正常運作的能力。

關鍵指標:

指標「能用」等級「好用」等級「出色」等級
Uptime95%(每月 36 小時停機)99.9%(每月 43 分鐘停機)99.99%(每月 4.3 分鐘停機)
Error Rate< 5%< 0.5%< 0.1%
MTTR< 24 小時< 1 小時< 15 分鐘
MTBF> 1 天> 30 天> 90 天
Data Durability有備份有定期備份 + 異地備援有即時複製 + 定期演練還原

常見的可靠性問題:

// 壞的做法:沒有 retry、沒有 timeout、沒有 circuit breaker
async function fetchUserData(userId) {
  const response = await fetch(`/api/users/${userId}`);
  return response.json();
}

// 好的做法:有 retry、有 timeout、有錯誤處理
async function fetchUserData(userId, options = {}) {
  const { maxRetries = 3, timeoutMs = 5000 } = options;

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), timeoutMs);

      const response = await fetch(`/api/users/${userId}`, {
        signal: controller.signal,
      });
      clearTimeout(timeoutId);

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }

      return response.json();
    } catch (error) {
      if (attempt === maxRetries) {
        logger.error('Failed to fetch user data after retries', {
          userId,
          attempts: maxRetries,
          error: error.message,
        });
        throw error;
      }
      // Exponential backoff
      await sleep(Math.pow(2, attempt) * 100);
    }
  }
}
安全性(Security)

安全性不是事後加上去的功能,而是產品品質的基本要求。

最低安全基線(OWASP Top 10 對應):

風險最低要求
Injection使用 parameterized query / ORM,絕不拼接 SQL
Broken Authentication密碼 bcrypt 雜湊、JWT 有過期時間、支援 MFA
Sensitive Data ExposureHTTPS everywhere、敏感資料加密儲存、log 不記錄 PII
XXE禁用外部實體解析
Broken Access Control每個 API 端點都有權限檢查,不只靠前端隱藏按鈕
Security Misconfiguration關閉 debug mode、移除預設帳號、定期更新依賴套件
XSS輸出編碼、CSP header、避免 innerHTML
Insecure Deserialization驗證所有反序列化的輸入
Using Components with Known Vulnerabilities定期執行 npm audit / snyk test
Insufficient Logging & Monitoring安全事件有 log、有告警、有定期 review
可擴展性(Scalability)

可擴展性不是「現在需要」,而是「未來需要時,改動的成本有多大」。

垂直擴展 vs 水平擴展:

擴展方式做法優點缺點
垂直擴展(Scale Up)升級硬體(更多 CPU、RAM)簡單、不需要改架構有上限、成本指數增長
水平擴展(Scale Out)增加更多實例理論上無上限需要無狀態設計、分散式系統的複雜度

設計時就該考慮的擴展性問題:

  1. Session 管理:Session 存在 server memory 裡嗎?還是存在 Redis 等外部 store?前者無法水平擴展。
  2. 檔案儲存:檔案存在 local disk 嗎?還是存在 S3 / GCS 等 object storage?前者無法水平擴展。
  3. 背景任務:長時間的任務(報表產生、大量資料處理)是在 API server 裡跑嗎?還是有獨立的 worker?前者會阻塞 API 請求。
  4. 資料庫:有讀寫分離嗎?有 connection pool 嗎?有考慮過 sharding 策略嗎?

3. 可維護性(Maintainability)

可維護性是好產品的「隱藏維度」——使用者看不到,PM 不會特別關注,但它直接決定了產品的長期生存能力。一個無法維護的產品,就像一棟沒有維修通道的大樓——剛蓋好時看起來很漂亮,但幾年後就會變成危樓。

程式碼品質(Code Quality)

程式碼品質不是「寫得漂亮」,而是「別人能不能快速理解和安全修改」。

可讀性(Readability)

// 壞的可讀性:變數名不具意義,邏輯不清楚
function proc(d) {
  const r = [];
  for (let i = 0; i < d.length; i++) {
    if (d[i].s === 1 && d[i].a > 18) {
      r.push(d[i]);
    }
  }
  return r;
}

// 好的可讀性:變數名有意義,邏輯清楚
function getActiveAdultUsers(users) {
  return users.filter(user =>
    user.status === UserStatus.ACTIVE && user.age > MINIMUM_ADULT_AGE
  );
}

測試覆蓋(Test Coverage)

測試覆蓋率是一個常被誤解的指標。重要的不是「數字」,而是「覆蓋了什麼」。

測試類型目的覆蓋什麼
Unit Test驗證單一函式/模組的邏輯正確性核心業務邏輯、邊界條件、錯誤處理
Integration Test驗證模組之間的互動正確性API 端點、資料庫操作、外部服務整合
E2E Test驗證使用者流程的完整性關鍵使用者路徑(登入、購買、結帳)

80% 的覆蓋率(涵蓋所有核心業務邏輯和關鍵路徑),遠比 95% 的覆蓋率(大量測試 getter/setter 和 trivial code)來得有價值。更多測試策略的討論,請參考 測試策略

文件完整度(Documentation)
文件類型目的內容更新頻率
README新人第一個看的文件專案簡介、如何 setup、如何 run、如何 test每次重大架構變更
API Docs前後端溝通的契約端點、參數、回應格式、錯誤碼每次 API 變更
ADR (Architecture Decision Records)記錄技術決策的「為什麼」背景、方案選項、決策理由、後果每次重大技術決策
Runbook維運手冊常見問題處理步驟、告警處理、災難復原每次 incident 後
Onboarding Guide新成員入職指南開發環境設定、程式碼架構導覽、常見 FAQ每季更新

ADR 範例:

# ADR-007: 選擇 PostgreSQL 作為主要資料庫
 
## 狀態
已採用(2024-03-15)
 
## 背景
系統需要一個支援 ACID 交易、JSON 查詢、全文搜尋的關聯式資料庫。
候選方案:PostgreSQL、MySQL、MongoDB。
 
## 決策
選擇 PostgreSQL。
 
## 理由
- 原生支援 JSONB 型別,可以同時滿足結構化和半結構化資料需求
- 內建全文搜尋功能,在中等規模下不需要額外的 Elasticsearch
- 團隊有 3 人有 PostgreSQL 經驗,只有 1 人有 MongoDB 經驗
- 開源授權,沒有商業授權風險
 
## 後果
- 需要學習 PostgreSQL 特有的 JSONB 查詢語法
- 如果未來全文搜尋需求超過 PostgreSQL 的能力,需要引入 Elasticsearch
- 需要設定 WAL(Write-Ahead Logging)和 replication
技術債管理(Technical Debt Management)

技術債不是壞事——它就像財務上的借貸一樣,有時候借錢(走捷徑)是合理的決策。問題在於你是否有意識地承擔技術債,以及是否有計畫地償還。

技術債的四個象限:

有意識的(Deliberate)無意識的(Inadvertent)
謹慎的(Prudent)「我們知道這不是最好的做法,但為了趕上市場窗口,我們先這樣做,之後再重構」「做完之後我們才發現,原來有更好的架構方式」
魯莽的(Reckless)「我們沒時間寫測試,先上線再說」「什麼是 design pattern?」

好的技術債管理:

  1. 記錄:每一筆技術債都應該被記錄(Issue tracker / TODO with ticket number)
  2. 評估:定期評估技術債的「利息」——它每天/每週造成多少額外的開發成本
  3. 排程:將技術債的償還排入 sprint,而不是「等有空再做」(永遠不會有空)
  4. 預算:每個 sprint 保留 15-20% 的容量用於償還技術債
// 壞的做法:沒有追蹤的 TODO
// TODO: fix this later

// 好的做法:有追蹤的技術債標記
// TECH-DEBT(JIRA-1234): 目前使用 polling 來檢查任務狀態,
// 應改為 WebSocket 以降低 API 負載。
// 預估影響:每日約 10,000 次不必要的 API 呼叫
// 預計償還:2024-Q4
部署能力(Deployment Capability)
指標「能部署」「好的部署」
部署頻率每月一次每天多次
部署方式手動 SSH 到伺服器執行腳本CI/CD Pipeline 自動化
部署風險每次部署都提心吊膽部署是日常事務,不需要特別準備
回滾能力出問題了再看辦法一鍵回滾到上一個版本
部署時間2 小時(含準備和驗證)15 分鐘(自動化)
部署影響需要停機維護零停機部署(Blue-Green / Canary)
Bus Factor 測試

Bus Factor(巴士指數) 是一個衡量團隊知識集中程度的指標:如果團隊中有幾個人同時被巴士撞到(或離職),專案就會陷入無法維護的困境?

Bus Factor風險等級狀況描述
1極高風險只有一個人知道系統怎麼運作。這個人離職,系統就完了
2-3高風險核心知識集中在少數人身上
4+可接受多人有足夠的知識來維護系統
全團隊理想任何人都能處理系統的任何部分

提高 Bus Factor 的方法:

  • Code Review:確保每個 PR 至少被一個(最好兩個)人 review
  • Pair Programming:定期進行配對開發,特別是在複雜的功能上
  • Knowledge Sharing Session:每週或每雙週舉辦技術分享
  • 文件化:將腦中的知識轉化為文件
  • 輪換 On-call:讓每個人都有機會處理維運問題

4. 商業價值(Business Value)

工程師常常忽略的一個事實是:產品存在的目的是創造商業價值,而不是展現技術實力。 一個技術上完美但沒人用的產品,不是好產品。

解決真正的問題

工程師有一個常見的傾向:喜歡解決「技術上有趣」的問題,而不是「使用者真正面對」的問題。

技術上有趣的問題使用者真正面對的問題
建構一個 event-driven microservice 架構使用者只是需要一個能穩定查詢訂單的功能
實作一個自訂的 ORM 框架使用者只是需要能快速搜尋商品
開發一個支援百萬併發的即時通訊系統目前的使用者只有 500 人,用 Firebase 就夠了
用 Kubernetes 管理微服務叢集單體應用 + 一台 VM 就能搞定目前的規模

YAGNI 原則(You Ain’t Gonna Need It): 不要為了「以後可能會用到」而過度設計。先解決現在的問題,當需求真正出現時再擴展。

Product-Market Fit (PMF) 的判斷指標

PMF 是衡量產品是否真正滿足市場需求的關鍵概念。以下是判斷 PMF 的實務指標:

指標尚未達到 PMF已達到 PMF
使用者獲取需要花大量行銷費用才有人用口碑傳播帶來自然增長
留存率D7 留存 < 20%D7 留存 > 40%
使用頻率使用者試用一次就不再回來使用者每天/每週固定使用
使用者回饋「還可以」「不太好用」「沒有這個工具我不知道怎麼辦」
Sean Ellis Test< 40% 的使用者會覺得「非常失望」如果產品消失> 40% 的使用者會覺得「非常失望」
付費意願免費都不太想用使用者主動問「有沒有付費版」
營收、成本與增長指標

作為工程師,理解基本的商業指標能幫助你做出更好的技術決策:

指標定義為什麼工程師該關心
CAC(客戶獲取成本)獲取一個新客戶的平均成本如果 CAC 太高,可能需要技術手段降低(如 SEO 優化、推薦系統)
LTV(客戶終身價值)一個客戶在整個生命週期帶來的收入LTV > CAC 才能持續經營,工程師可以透過提升留存來增加 LTV
MRR(月經常性收入)每月的經常性收入MRR 的成長率反映產品的健康度
Burn Rate每月的支出速度直接影響公司能活多久,工程師的技術決策(如選用昂貴的雲服務)會影響 Burn Rate
Churn Rate使用者流失率高 Churn 可能是 UX 問題、效能問題、或可靠性問題——都是工程師能改善的
MVP 陷阱

MVP(Minimum Viable Product)是創業圈最常被提到也最常被誤解的概念。

常見的 MVP 誤區:

誤區描述後果
太 Minimal只做了一個什麼都不能幹的 demo使用者試用後覺得「這也叫產品?」,留下負面印象
太 Viable想要把所有功能都做完才上線永遠做不完,錯過市場窗口
M 但不 V做了一個很小的東西,但它不能完成任何完整的使用者任務無法驗證 PMF,收集不到有意義的回饋
V 但不 M做了一個完整的產品,但花了太長時間等到上線時,市場已經變了

正確的 MVP 心態:

MVP 的重點不是「做最少的功能」,而是「用最小的投入來驗證最大的假設」。一個好的 MVP 應該:

  1. 完成一個完整的使用者任務:使用者可以從頭到尾完成至少一件事情
  2. 在那個任務上做到足夠好:不需要完美,但需要「可用」
  3. 能收集回饋:內建 analytics、feedback 機制
  4. 能快速迭代:架構允許快速修改和發布

5. 團隊與流程(Team & Process)

好產品不只是好程式碼,更是好團隊用好流程做出來的。團隊的運作方式,直接決定了產品的品質上限。

知識的分散程度

知識不應該只存在某個人的腦裡。以下是知識集中的警訊:

  • 「這個功能只有小明會改」
  • 「那個 deployment script 只有老王知道怎麼跑」
  • 「這段程式碼的邏輯太複雜了,除了原作者沒人敢動」
  • 「上次出事的時候,找不到那個人來處理」

知識分散的健康度評估:

等級描述風險
Level 1:單點知識某個關鍵知識只有一個人知道這個人休假或離職就出事
Level 2:口頭傳承知識透過口頭傳遞,沒有文件傳遞過程中會失真
Level 3:有文件知識被寫成文件文件可能過時
Level 4:有文件且有流程知識有文件,且有定期更新的流程成本較高但風險最低
Level 5:嵌入系統知識被嵌入自動化系統(CI/CD、IaC、自動化測試)最理想的狀態
新成員的上手速度

新成員從入職到能夠獨立開發功能的時間,是衡量團隊成熟度的重要指標。

上手時間狀態可能的問題
< 1 週優秀有完整的 onboarding guide、開發環境一鍵設定、良好的程式碼架構
1-2 週良好大部分流程有文件,偶爾需要問人
2-4 週可接受文件不完整,需要大量口頭指導
1-3 個月有問題缺乏文件、程式碼品質差、架構混亂
> 3 個月嚴重問題系統極度複雜或混亂,知識嚴重集中在少數人身上

改善上手速度的具體做法:

  1. 開發環境自動化:一個指令(make setupdocker compose up)就能啟動所有服務
  2. First Task Ready:準備好適合新人的第一個任務(不太難、有明確範圍、能接觸核心功能)
  3. Buddy System:指定一個 mentor,新人有問題可以直接問
  4. 程式碼導覽:錄製或撰寫程式碼架構的導覽,解釋各模組的職責和關係
問題回報到修復的時間

從使用者回報問題到問題被修復並部署上線的時間,反映了團隊的回應能力。

一個健康的問題處理流程:

使用者回報 → 問題分類 → 指派負責人 → 調查根因 → 修復 → 測試 → 部署 → 驗證 → 通知使用者
    │           │          │            │         │       │       │       │         │
    ▼           ▼          ▼            ▼         ▼       ▼       ▼       ▼         ▼
  < 1h       < 2h       < 4h        < 1 day    < 2d    < 4h    < 1h    < 2h      < 1h
                                                              (CI/CD)

總計: 對於非緊急問題,從回報到修復上線應該在一週內完成。對於緊急問題(P0/P1),應該在數小時內完成。

更多關於 incident 處理的流程,請參考 事件管理方法論

決策留不留紀錄

團隊的技術決策如果只存在口頭討論中,會面臨以下問題:

  1. 無法追溯:三個月後沒人記得為什麼選了某個方案
  2. 無法學習:新成員不知道決策的背景和考量
  3. 重複討論:同樣的議題反覆被提出,因為沒人記得已經討論過
  4. 無法問責:出問題時不知道當時的決策依據是什麼

ADR(Architecture Decision Records) 是解決這個問題的最佳實踐。每一個重大技術決策都應該記錄為一個 ADR,包含:

  • 背景(Context):什麼情境下需要做這個決策
  • 方案(Options):有哪些可選方案
  • 決策(Decision):最終選了哪個方案
  • 理由(Rationale):為什麼選這個方案
  • 後果(Consequences):這個決策的正面和負面影響

好產品的生命週期

產品不是靜態的——它會經歷不同的生命週期階段,而在每個階段,「品質」的定義和優先序都不同。

    ┌─────────────────────────────────────────────────────────────────┐
    │                                                                 │
    │   MVP        Growth        Maturity         Sunset              │
    │    │            │              │               │                │
    │    ▼            ▼              ▼               ▼                │
    │   驗證假設     快速增長       穩定營運         優雅退場          │
    │                                                                 │
    │   ───────────────────────────────────────────────── → 時間      │
    └─────────────────────────────────────────────────────────────────┘
面向MVP 階段Growth 階段Maturity 階段Sunset 階段
核心目標驗證 PMF快速獲取用戶穩定營運、最大化利潤優雅退場、資料遷移
UX 標準核心流程可用即可優化關鍵路徑全面優化、A/B testing維持基本可用
技術品質能跑就好解決效能瓶頸全面監控、SLO最小維護
測試覆蓋核心流程的 E2E 測試補上 integration test全面覆蓋只保留關鍵路徑
可維護性可以有技術債開始償還高利息的技術債嚴格的程式碼品質標準凍結功能開發
文件README 夠用就好補上 API docs、ADR完整的文件體系遷移指南
監控基本的 uptime checkAPM、error tracking全面的 observability基本告警
團隊規模2-5 人5-20 人20+ 人1-3 人
部署頻率隨時部署每天多次有節奏地部署(每週)只有 hotfix
技術債容忍度高(有意識地承擔)中(邊做邊還)低(嚴格管控)不再新增

關鍵洞察: 在 MVP 階段追求完美是浪費;在 Maturity 階段不追求品質是自殺。工程師需要根據產品的生命週期階段來調整品質標準。

這些階段的規劃方法,可以參考 系統規劃方法論Release 方法論 的詳細討論。


衡量產品品質的指標

定義了好產品的五個維度後,我們需要具體的指標來衡量。以下將指標分為三類:技術指標、業務指標和開發者體驗指標。

技術指標

DORA Metrics

DORA(DevOps Research and Assessment)提出的四個關鍵指標,是衡量軟體交付效能的業界標準:

指標定義Elite 水平High 水平Medium 水平Low 水平
Deployment Frequency部署到生產環境的頻率按需求(一天多次)每天到每週每週到每月每月到每半年
Lead Time for Changes從 commit 到上線的時間< 1 天1 天 - 1 週1 週 - 1 個月1 - 6 個月
Mean Time to Restore (MTTR)服務中斷到恢復的時間< 1 小時< 1 天< 1 週> 6 個月
Change Failure Rate部署導致失敗的比例0-15%16-30%16-30%> 45%

為什麼 DORA Metrics 重要?

DORA 的研究發現,這四個指標之間是正相關的——部署頻率高的團隊,失敗率反而更低。這打破了「部署越頻繁越容易出事」的直覺。原因在於:頻繁部署意味著每次變更量小,問題更容易發現和定位,回滾的風險也更低。

SLI / SLO / SLA
概念定義由誰設定範例
SLI (Service Level Indicator)服務品質的度量指標工程團隊API 回應時間(P99)、可用性百分比、錯誤率
SLO (Service Level Objective)服務品質的目標值工程團隊 + 產品團隊P99 回應時間 < 500ms、可用性 > 99.9%
SLA (Service Level Agreement)對外承諾的服務品質業務團隊 + 法務可用性 99.9%,低於此標準提供服務費用減免

設定 SLO 的實務建議:

  1. 從使用者體驗出發:SLO 應該反映使用者的期望,而不是技術限制
  2. 不要設太高:99.999% 的可用性聽起來很棒,但代價是巨大的工程投入。大多數產品 99.9% 就足夠了
  3. 有 Error Budget:SLO 留下的「允許失敗空間」就是 Error Budget。例如 SLO 是 99.9%,那每月有 43 分鐘的 Error Budget 可以用來做部署、實驗
  4. 定期 review:SLO 不是設完就不管,應該每季度 review 一次
測試覆蓋率的正確解讀

測試覆蓋率(Test Coverage)是最常被引用也最常被誤解的程式碼品質指標。

覆蓋率解讀
0-30%幾乎沒有測試。任何修改都是在冒險
30-60%核心邏輯可能有測試,但邊界條件和錯誤處理可能沒有
60-80%合理的覆蓋。大部分重要路徑都有測試
80-90%良好的覆蓋。邊界條件和錯誤處理也有測試
90-100%需要檢查是否有「為了提高覆蓋率而寫的無意義測試」

比覆蓋率數字更重要的問題:

  • 核心業務邏輯有測試嗎?
  • 錯誤處理路徑有測試嗎?
  • 邊界條件有測試嗎?
  • 測試是否真的驗證了行為,而不只是呼叫了函式?
  • 測試是否會在程式碼行為改變時失敗?(如果改了行為但測試不會失敗,那測試沒有在保護你)

業務指標

使用者互動指標
指標定義計算方式健康標準
DAU / MAU日活/月活使用者數每天/每月至少使用一次的獨立使用者數DAU/MAU ratio > 20%(表示使用者經常回來)
Retention Rate留存率D1/D7/D30 在對應天數後仍在使用的使用者比例D7 > 40%(因產品類型而異)
Churn Rate流失率在特定時期內停止使用的使用者比例月 Churn < 5%(SaaS)
Session Duration平均使用時長每次使用的平均時間因產品類型而異
Feature Adoption功能採用率使用特定功能的使用者佔總使用者的比例核心功能 > 80%
NPS(Net Promoter Score)

NPS 是衡量使用者忠誠度的標準指標。透過一個問題衡量:「你會有多大可能推薦這個產品給朋友?(0-10 分)」

分數分類意義
9-10推薦者(Promoter)忠實用戶,會主動推薦
7-8被動者(Passive)滿意但不特別忠誠
0-6批評者(Detractor)不滿意,可能散播負面口碑

NPS = 推薦者比例 - 批評者比例

NPS 範圍評價
> 70世界級(Apple、Netflix 等級)
50-70優秀
30-50良好
0-30有改善空間
< 0有嚴重問題
客服工單量

客服工單(Support Ticket)的數量和類型,是產品品質的一面鏡子:

工單類型反映的問題技術對策
「我不知道怎麼用」UX 設計不直覺改善 UI、增加引導
「功能壞了」可靠性問題增加測試、改善監控
「速度太慢」效能問題效能優化、CDN、快取
「資料不見了」資料可靠性問題備份、audit log
「我被 hack 了」安全性問題安全稽核、滲透測試

健康指標: 每 1000 個活躍使用者的月工單數量。如果這個數字持續上升,表示產品品質在下降。

開發者體驗指標

開發者體驗(Developer Experience, DX)是衡量「做出好產品的能力」的指標。好的 DX 意味著工程師能更快、更安全地交付有價值的功能。

指標定義優秀水平有問題的水平
Onboarding Time新人從入職到能獨立開發的時間< 1 週> 1 個月
Build Time本地建置的時間< 2 分鐘> 10 分鐘
CI Pipeline TimeCI 從 commit 到完成的時間< 10 分鐘> 30 分鐘
Time to Production從 merge 到生產環境的時間< 1 小時> 1 週
Dev Environment Setup設定開發環境的時間< 30 分鐘> 1 天
PR Review TimePR 從建立到被 review 的時間< 4 小時> 2 天
Developer Satisfaction開發者對工具和流程的滿意度> 4/5< 3/5

為什麼 DX 指標重要?

因為 DX 直接影響了產品交付的速度和品質:

  • Build Time 太長 → 開發者避免頻繁測試 → 品質下降
  • CI Pipeline 太慢 → 開發者等待時 context switch → 效率下降
  • PR Review Time 太長 → 開發者堆積 PR → 衝突增加 → 品質下降
  • Onboarding Time 太長 → 新人無法快速產出 → 團隊擴展困難

常見反模式

在追求「好產品」的過程中,有四種常見的反模式(Anti-patterns),會讓團隊偏離正確的方向。

1. 技術完美主義(Technical Perfectionism)

症狀:

  • 追求 100% 測試覆蓋率,但產品還沒有任何使用者
  • 花三週設計一個「完美的」資料庫 schema,但需求還在變
  • 重構已經運作良好的程式碼,只因為它「不夠優雅」
  • 引入最新的技術棧,只因為想學新東西

後果:

  • 產品永遠無法上線(或上線時市場已經變了)
  • 團隊士氣受挫,因為做了很多技術工作但看不到產品進展
  • 公司資源浪費在使用者不在乎的事情上

解方:

  • 設定明確的「品質基線」(baseline),而不是追求完美
  • 用「使用者價值」來判斷技術投入的優先級
  • 問自己:「如果我不做這件事,使用者會不會受到影響?」
  • 接受「夠好就好」——Perfect is the enemy of good

自我檢測: 如果你花在 refactoring 和技術優化上的時間,超過花在交付使用者價值的時間,你可能陷入了技術完美主義。

2. 快速交付陷阱(Ship Fast Trap)

症狀:

  • 每週 ship 5 個新功能,但品質越來越差
  • Bug 的增長速度比功能還快
  • 沒有測試、沒有 code review、沒有文件
  • 「我們之後會回來修」——但從來沒有「之後」
  • 技術債堆積如山,每做一個新功能都需要繞過之前的 hack

後果:

  • 系統越來越脆弱,一個小改動可能引發連鎖故障
  • 開發速度反而越來越慢(因為要花大量時間處理 bug 和 workaround)
  • 優秀的工程師離職(因為不想在一堆糟糕的程式碼上工作)
  • 使用者對品質失去信心

解方:

  • 設定「品質門檻」:每個 PR 必須通過 code review、有必要的測試
  • 每個 sprint 保留 20% 的容量用於技術債償還
  • 追蹤「修 bug 的時間佔總開發時間的比例」——如果超過 30%,要亮紅燈
  • 寧願少做一個功能,也不要犧牲品質

自我檢測: 如果你的團隊花在修 bug 上的時間超過花在新功能上的時間,你可能陷入了快速交付陷阱。

3. 指標遊戲(Metric Gaming)

症狀:

  • 為了提高測試覆蓋率,寫了大量 expect(true).toBe(true) 之類的測試
  • 為了降低 MTTR,把告警的嚴重等級調低(不告警就沒有 incident!)
  • 為了提高部署頻率,把一個大變更拆成十個無意義的小部署
  • 為了提高 DAU,用煩人的 push notification 把使用者拉回來

根本問題: 當指標變成目標(而不是工具),人們會找到最佳化指標的方式,而不是最佳化指標背後真正要衡量的東西。這就是 Goodhart’s Law:「當一個指標變成目標,它就不再是好的指標。」

解方:

  • 使用多個互相制衡的指標(例如:同時看部署頻率和 change failure rate)
  • 關注指標的趨勢,而不是絕對數字
  • 定期問:「這個指標是否仍然反映我們真正關心的事情?」
  • 鼓勵質疑指標的文化——如果某個指標持續改善但使用者體驗沒有變好,那指標可能有問題

自我檢測: 如果你的所有指標都在改善,但使用者的回饋沒有變好,你可能陷入了指標遊戲。

4. 英雄文化(Hero Culture)

症狀:

  • 每次出問題,都是同一個人半夜起來修
  • 某個「10x developer」寫了系統最核心的部分,但只有他看得懂
  • 團隊依賴個人的超級能力,而不是系統化的流程
  • 「沒有 XXX 我們不行」

後果:

  • Bus Factor = 1,這個人離開就完了
  • 其他團隊成員得不到成長,因為所有有挑戰性的工作都被英雄做了
  • 英雄本人也會 burnout
  • 系統的品質取決於個人狀態,而不是流程保障

解方:

  • 將英雄的知識文件化和系統化
  • 強制 code review——包括英雄的程式碼
  • 實施 on-call rotation——每個人都要參與維運
  • 將「能教會別人」作為績效指標之一
  • 不要獎勵「救火」,要獎勵「防火」

自我檢測: 如果你的團隊中某個人休假時大家會特別緊張,你可能有英雄文化的問題。


實務建議

在理解了好產品的五個維度、生命週期、衡量指標和常見反模式之後,以下是一些可以立即採用的實務建議。

1. 產品品質是平衡,不是最大化

沒有一個產品能在所有維度上都做到完美。資源是有限的,你必須做出 trade-off。

Trade-off 矩陣:

情境優先的維度可以暫時犧牲的維度
新創 MVP商業價值、使用者體驗可維護性、測試覆蓋
企業軟體可靠性、安全性、可維護性部署速度
消費者 App使用者體驗、效能內部程式碼品質
金融系統安全性、可靠性、稽核開發速度
快速成長期可擴展性、效能功能完整度

2. 在不同階段有不同的品質基線

不要用 Maturity 階段的標準來要求 MVP 階段的產品,也不要用 MVP 階段的標準來運作 Maturity 階段的系統。

MVP 階段的品質基線:

## MVP Quality Baseline
 
### 必須做到的(Non-negotiable)
- [ ] 核心使用者流程可以走通
- [ ] 基本的錯誤處理(不會 crash、使用者看到友善的錯誤訊息)
- [ ] HTTPS + 基本的 authentication
- [ ] 有備份
- [ ] 有基本的 monitoring(uptime check + error tracking)
 
### 應該做到的(Should have)
- [ ] 核心流程的自動化測試
- [ ] README 和基本的 API docs
- [ ] CI Pipeline
- [ ] 基本的 logging
 
### 可以之後再做的(Can defer)
- [ ] 完整的測試覆蓋
- [ ] 效能優化
- [ ] 完整的文件
- [ ] 多環境(staging、pre-prod)

Maturity 階段的品質基線:

## Maturity Quality Baseline
 
### 必須做到的(Non-negotiable)
- [ ] 完整的測試覆蓋(unit + integration + E2E)
- [ ] SLO 設定並持續監控
- [ ] 完整的 observability(metrics + logs + traces)
- [ ] 安全性稽核定期執行
- [ ] CI/CD 自動化部署
- [ ] 災難復原計畫並定期演練
- [ ] 完整的文件(README、API docs、ADR、Runbook)
- [ ] On-call rotation
 
### 應該做到的(Should have)
- [ ] Chaos Engineering
- [ ] A/B testing 框架
- [ ] Feature flag 系統
- [ ] 效能 regression 偵測

3. 技術債不是壞事,但要有意識地管理

技術債管理的三步驟:

  1. 可見化:把所有技術債記錄在 Issue Tracker 中,並標記優先級
  2. 量化:估算每筆技術債的「利息」——它每週造成多少額外的開發成本(例如:這個 workaround 每次修改相關功能都需要多花 2 小時)
  3. 排程:根據利息高低排序,在每個 sprint 安排固定比例的容量來償還

技術債的分類和處理策略:

利息等級描述處理策略
高利息每天都在影響開發效率的債立即安排償還
中利息偶爾會碰到的債排入下 1-2 個 sprint
低利息存在但不影響日常開發的債有空再還,或在重構時順便處理
零利息程式碼不優雅但完全沒有影響的債不處理。這不是債,這是你的潔癖

4. “Good Enough for Now” vs “Do It Right”

每次面對技術決策時,你需要判斷:這個地方需要「現在做好」還是「之後再來」。

判斷框架:

問自己以下四個問題:

  1. 影響範圍有多大? 如果這個決策影響整個系統的架構,現在就做好;如果只影響一個功能,可以之後再改。

  2. 改動的成本會隨時間增加嗎? 如果現在不做,之後的改動成本會大幅增加(例如資料庫 schema 設計),現在就做好;如果改動成本不會增加太多(例如 UI 微調),可以之後再做。

  3. 使用者會受到影響嗎? 如果品質問題會直接影響使用者體驗,現在就做好;如果只是內部程式碼品質,可以適度妥協。

  4. 有學習價值嗎? 如果先用簡單的方式做,能讓你更快收集使用者回饋,進而驗證方向是否正確,那先做簡單版本可能更合理。

決策矩陣:

改動成本不會增加改動成本會增加
影響範圍小之後再做(Good enough for now)之後再做,但記錄成技術債
影響範圍大值得現在做好,但不要過度設計現在就做好(Do it right)

總結

好產品不是一個絕對的標準,而是在特定的階段、特定的資源限制下,對五個維度——使用者體驗、技術品質、可維護性、商業價值、團隊與流程——做出最適當的平衡。

作為工程師,我們需要:

  1. 跳出技術泡泡:好產品不只是好程式碼。使用者體驗和商業價值同樣重要。
  2. 根據階段調整標準:MVP 階段的品質標準和 Maturity 階段不同,不要用錯標準。
  3. 用指標說話:建立技術指標、業務指標和開發者體驗指標的完整框架,用數據而不是直覺來判斷品質。
  4. 避免反模式:技術完美主義、快速交付陷阱、指標遊戲、英雄文化——任何一個都可能讓你偏離正軌。
  5. 有意識地做決策:每一個 trade-off 都應該是有意識的選擇,並且記錄下來。

最終,好產品的標準只有一個:在使用者需要的時候,穩定地、可靠地、愉快地為他們解決問題。 這聽起來很簡單,但要做到這一點,需要在技術、設計、商業和團隊管理上同時下功夫。


Proto 實踐對照

Proto 本身就是一個產品——它的使用者是開發團隊。一個好的 Proto 符合本文所述的產品特質:解決真實痛點(每次從零建專案的重複成本)、提供完整體驗(clone 下來就能跑)、持續演進(根據 Gap Analysis 補齊落差)。詳見 Proto 規劃方法論


延伸閱讀

系列文章:

推薦書籍:

  • Inspired: How to Create Tech Products Customers Love — Marty Cagan
  • The Lean Startup — Eric Ries
  • Accelerate: The Science of Lean Software and DevOps — Nicole Forsgren, Jez Humble, Gene Kim
  • Designing Data-Intensive Applications — Martin Kleppmann
  • Don’t Make Me Think — Steve Krug

推薦資源:

  • DORA State of DevOps Report:每年發布的軟體交付效能研究報告
  • Google SRE Books:Google 的站點可靠性工程實踐指南
  • OWASP Top 10:Web 應用程式安全風險的年度報告
  • Nielsen Norman Group:使用者體驗研究的權威資源