← 所有文章2026.10.01 · 軟體設計

先別急著設計:把理想需求一層一層剝回真正的問題

業主描述的是終局願景,工程團隊卻可能把它當成今天的規格。這是我從需求釐清、成本失控與架構設計中學到的方法。

結論先行

我做過幾次架構規劃之後,最大的體會不是要更早選資料庫、畫更多服務,反而是:在理解真正的問題以前,不要太快把一句願景翻譯成系統。

業主談需求時,經常把今天、幾年後,以及理想狀態放在同一句話裡。他不一定知道哪些能力昂貴、哪些假設會改變整套資料模型;工程師也可能把「以後希望可以」聽成「第一版必須完整支援」。雙方都沒有說錯,只是站在不同時間尺度、使用不同語言。

如果沒有先對齊,團隊很容易為尚未發生的規模設計過多抽象、服務與部署單元。程式碼變複雜,交付時間拉長,雲端與維運成本一起增加,真正需要解決的問題反而更晚才被驗證。

我現在的做法是把需求像洋蔥一樣逐層剝開:

  1. 這個想法最終想改變什麼業務結果?
  2. 現在是誰,在什麼情境下,遇到什麼阻礙?
  3. 哪一項能力不做,系統今天就無法成立?
  4. 哪些只是合理的未來方向,還沒有觸發條件?
  5. 我們能否先解決當下,同時留下低成本、可測試的延伸接縫?

系統分析的價值,不是把客戶說的每一句話都變成 feature,而是共同找出:現在值得付錢解決的問題是什麼。

願景和版本需求不是同一件事

一位業主可能會說:

未來要支援不同地區、不同客戶、不同計價方式,流量成長後也不能停機。

這句話對產品方向很重要,但它還不是可以直接估工的需求。裡面至少混合了幾個不同問題:

  • 多地區是語言、幣別、法規,還是資料落地位置?
  • 多客戶是幾個固定合作方,還是任何人都能自助建立租戶?
  • 不同計價方式是幾張價格表,還是可組合的規則引擎?
  • 不能停機是營業時間內要穩定,還是需要跨區域自動容錯?
  • 成長指的是已簽約客戶、業務預測,還是一個還沒被驗證的可能性?

如果工程師直接以最寬的解讀設計,可能很快得到多租戶、事件驅動、跨區部署、規則引擎和完整權限平台。但真正的第一版,也許只有內部人員替少數企業客戶建帳號,價格每季才調整一次。

問題不在於那些架構技術不好,而是採用的時機沒有證據支持。

flowchart LR
  V[終局願景] --> O[業務結果]
  O --> U[現在的使用者與流程]
  U --> P[此刻真正的阻礙]
  P --> N[第一版必要能力]
  N --> S[可延伸的設計接縫]
  S --> T[由證據觸發下一階段]

先拆時間,再談架構

我習慣把規劃分成短、中、長三個時間層,但不把三層都當成同等承諾。

時間層 要回答的問題 架構處理方式
現在 沒有什麼能力就不能交付或營運? 實作、測試並監控
接下來 哪些需求已有明確訊號,可能在近期出現? 保留介面、資料邊界或替換點
以後 哪些只是方向,時間、規模與形式都未確定? 記錄假設與觸發條件,暫不建造

這裡最重要的差別是:規劃未來,不等於現在實作未來。

好的架構不是完全忽略未來,而是知道要在哪裡留下彈性。例如,今天只有單一付款供應商,不需要先做一套萬用 orchestration platform;但可以把供應商回傳狀態隔離在 adapter 後面,讓核心訂單模型不直接依賴某家的欄位。這是一個便宜的接縫,不是一套提前建好的未來系統。

用第一性原理追問:這個限制真的存在嗎?

這段經驗讓我重新理解大家常說的 first-principles thinking。它不是把每個問題都講得很哲學,而是暫時放下「通常系統都這樣做」,回到幾個最基本的事實:

  • 現在有多少使用者與請求?尖峰如何發生?
  • 哪些資料必須正確,哪些畫面只要最終一致?
  • 失敗一次的業務代價是什麼?可以人工恢復嗎?
  • 哪些要求來自法規、合約或真實營運限制?
  • 哪些只是我們對未來的想像?

只有經過這一層,架構選擇才不會從名詞出發,而是從限制出發。

例如,「未來流量可能很大」不是容量需求。可以進入設計的說法應該更接近:

目前:尖峰請求量與主要瓶頸已有量測。
目標:在預期成長區間內維持既定延遲與錯誤率。
觸發:當持續使用率或排隊時間超過門檻,才啟動下一階段拆分。
例外:若簽下具有不同資料隔離要求的客戶,重新檢視 tenancy 設計。

不一定要在第一天就有精準數字,但必須分清楚哪些是量測、哪些是預測、哪些只是尚待驗證的假設。

我怎麼把洋蔥一層層剝開

現在遇到一個很大的需求,我不會立刻問「要用什麼技術」,而是依序問下面五層。

第一層:想要的結果

先問業務為什麼想做,而不是想做什麼功能。

  • 希望減少人工操作?
  • 希望更快接下一個客戶?
  • 希望降低錯帳或漏單?
  • 希望管理者可以看到進度?

相同的 feature 名稱,背後可能是完全不同的成功標準。

第二層:現在的真實流程

請對方帶著團隊走一次現在怎麼做。誰先收到資料、在哪裡判斷、誰核准、失敗後怎麼補救。很多真正的需求,只有在動詞、交接點和例外中才看得見。

第三層:範圍與頻率

確認使用者、交易、資料量與變更頻率。不是為了假裝預測精準,而是避免把一年幾次的管理操作,當成每秒都要自動決策的核心路徑。

第四層:失敗與責任

如果功能延遲、重複或失敗,會發生什麼?能否重試?是否牽涉金錢、權限、法規或不可逆資料?這一層決定真正需要投入多少可靠性成本。

第五層:未來的觸發條件

不要只寫「之後可能需要」,而是約定何時重新評估:新市場確定上線、合作方超過某個複雜度、人工處理時間開始影響營運,或監控顯示單體已碰到容量瓶頸。

剝到最後,原本龐大的需求通常會變成三種東西:現在要做的能力、現在只需保留的接縫,以及尚未有證據、不該進入本期成本的想法。

可擴展性不是預先把所有東西拆開

「要考慮未來擴展」最容易被誤解成先做微服務、通用規則引擎或多區域架構。這些選擇有時必要,但每一項都會引入新的成本:網路失敗、資料一致性、部署、監控、權限,以及更多團隊協作界面。

我更在意的是幾種比較樸素的彈性:

  • 業務規則集中在清楚的 domain boundary,不散落在 controller 和 UI。
  • 外部系統透過 adapter 進入,不讓供應商格式污染核心模型。
  • Schema 可以演進,重要事件與 migration 有版本。
  • 模組之間有明確契約,但在證明需要以前不急著拆成獨立服務。
  • 有監控能告訴我們何時真的碰到容量或可靠性限制。

這種設計保留了未來選項,但不需要今天就承擔完整的分散式系統成本。

flowchart TB
  R[現在的核心需求] --> D[清楚的 domain boundary]
  D --> A[外部系統 adapter]
  D --> C[穩定契約與可演進 schema]
  D --> M[容量與錯誤監控]
  M -->|門檻尚未出現| K[維持簡單]
  M -->|證據出現| E[拆分或擴展]

估工時,連假設一起交付

需求尚未完全釐清時,直接報一個單點工期,容易讓探索中的想法看起來像固定承諾。現在我會把估算和假設綁在一起:

項目 應該寫清楚的內容
使用情境 誰使用、從哪裡開始、完成什麼結果
本期範圍 這一版明確包含與不包含什麼
容量基準 目前量測、合理區間與尖峰型態
風險 尚未確定、可能改變資料或流程的地方
擴充接縫 這次保留哪些介面,但不提前建造哪些能力
重新評估條件 哪個業務或技術證據出現時再升級

這樣做不是推卸承諾,而是讓成本和決策建立在同一套認知上。業主也能清楚選擇:現在為哪一種風險付費,哪些成本等訊號出現再投入。

一個我會使用的需求句型

我現在會把抽象願景改寫成下面這種格式:

當 [某類使用者] 在 [具體情境] 需要 [完成某項工作] 時,
系統應提供 [最小必要能力],
讓 [可觀察的業務結果] 發生。

本期假設:[流量、角色、地區、資料與操作頻率]
本期不含:[尚未驗證的未來能力]
保留接縫:[未來可替換或擴展的位置]
重新評估:[能被觀察的觸發條件]

這個格式會迫使團隊把「夢想中的平台」和「下一步要交付的產品」分開。

系統分析不是把願景縮小,而是安排正確順序

我以前會擔心,把未來功能拿出第一版是不是太保守。後來才發現,真正保守的是花很長時間建造尚未被使用者驗證的架構,最後讓系統難以改變。

先解決當下,不代表只顧眼前。成熟的做法是同時做到三件事:

  • 用最小但完整的能力處理今天的核心流程。
  • 在高機率變動處留下清楚、便宜的設計接縫。
  • 用業務與系統訊號決定何時投入下一階段。

系統不是一次設計完成的。它應該隨著我們對問題的理解、真實流量與營運限制逐步演進。架構師的工作,也不是預測所有未來,而是讓團隊在未來到來時仍有選擇。

規劃前的檢查清單

  • 我們描述的是業務結果,還是直接跳到了功能與技術?
  • 現行流程、角色、例外與人工補救是否真的走過一次?
  • 現在的流量與失敗代價來自量測,還是想像?
  • 短、中、長期需求是否被分開,而不是一起承諾?
  • 每個昂貴的架構選擇都有現在的限制支撐嗎?
  • 未來能力是否有明確的重新評估條件?
  • 我們留下的是擴充接縫,還是一套沒人使用的完整平台?
  • 估算是否同時列出假設、範圍外項目與風險?

我認為這是系統分析最深、也最容易被低估的一部分:不是把需求收得越完整越好,而是持續追問,直到所有人都在談同一個問題、同一個時間尺度,以及同一筆值得現在投入的成本。