跳轉到

2.4 邊界條件與 Edge Cases#

魔鬼藏在細節裡#

一個系統 90% 的邏輯可能只花 10% 的時間寫完,而剩下的 10% 邊界條件,往往要花 90% 的時間——還會造成最多的 Bug。這不是誇張。邊界條件(Edge Cases)是軟體工程中最容易出錯、也最考驗功力的一環。

什麼是邊界條件?就是那些「正常流程之外」的特殊情況。回想上一節的使用例替代流程——那些就是邊界條件的具體表現。

以一個最簡單的函式為例:「計算折扣後的金額」。

def apply_discount(price, discount_rate):
    return price * (1 - discount_rate)

看起來沒問題。但如果我們追問邊界條件:

  • discount_rate = 0.5(五折)正常
  • discount_rate = 1.0(全免)?要不要允許?
  • discount_rate = 1.5(超過 100% 折扣)?會不會算成負數?
  • price 是負數?應該拒絕
  • price 是字串 "100"?型別錯誤
  • discount_rate 是 None?會崩潰
  • 金額要不要四捨五入?用哪種捨入法?

這些就是邊界條件。真正健壯的系統,必須對每一種情況都定義清楚的行為——要嘛拋出明確的錯誤,要嘛有合理的預設值。

邊界條件的分類#

以系統化方式思考邊界條件,能避免遺漏。常見的分類有:

輸入邊界#

  • 空值:null、空字串、空列表
  • 極值:0、1、最大值、最小值、負數
  • 型別不匹配:數字當字串、錯誤的資料格式
  • 異常字元:Unicode、Emoji、特殊符號、超長字串
  • 重複/訂單衝突:重複提交、重複訂單

時序邊界#

  • 過期:優惠券過期、權限過期、Session 過期
  • 時間極限:00:00、23:59、跨年夜、二月最後一天
  • 時區:不同時區的使用者、日光節約時間
  • 中斷:使用者中途斷線、取消、重試

狀態邊界#

  • 非法狀態轉移:取消已經取消的訂單、退貨超過期限
  • 併發衝突:兩個使用者同時改同一個資料、資源競爭
  • 外部依賴失效:第三方 API 超時、資料庫連線中斷

數量邊界#

  • 上限:購物車最多幾件、單次最多匯款多少
  • 最小:刪除最後一個項目後系統還能不能運作
  • 溢位:數字超過型別範圍、堆積過多

為什麼邊界條件這麼容易遺漏#

遺漏邊界條件的根本原因,是我們的思維傾向於沿著「快樂路徑」(Happy Path)前進——也就是預設一切正常。這可能是人類心智的一種偏誤:我們設計時想像的是「理想狀況」,而真實世界充滿了例外。

另一個原因是邊界條件往往發生在極罕見的時刻——一年遇不到幾次。於是開發者會覺得「不值得處理」。但正是這些罕見時刻,一旦出錯,後果最嚴重:交易多扣款、併發造成資料錯亂、資安漏洞。

軟體工程的成熟,很大程度就體現在對邊界條件的敬畏。 資深工程師與新手的差別,往往不在於寫出正常流程,而在於能否系統性地想到「這裡會怎樣出錯」。

AI 時代:邊界條件的雙面性#

AI 對邊界條件的影響是雙面的,值得深思:

AI 的優勢:AI 在生成程式碼時,可以主動補齊許多你「忘了想到」的邊界條件——它看過海量程式碼,知道常見的坑。例如你讓它寫「折扣計算」,它很可能自動加上型別驗證、負數檢查。這讓邊界條件的「第一輪」覆蓋變得好很多。

AI 的盲點:但 AI 的盲點,恰恰是那些依賴特定業務情境的邊界條件。AI 不知道你的餐廳「滿 12 人可以自動加開桌位」、不知道你的法規「退款必須在 7 天內處理」、不知道你的老闆「討厭負金額攪亂報表」。這些需要深入了解業務才會知道的規則,AI 無法替你想到。

因此正確的態度是:把 AI 當成「邊界條件的得力助手」,但不要當成「邊界條件的保證人」。人類仍然需要系統性地審查、測試 AI 產出的邊界處理是否完整(見第 5 章)。

系統性地挖掘邊界條件#

有幾個實用的方法,可以減少遺漏:

  1. Red Teaming(紅隊思考):故意請人(或 AI)站在「想要把系統搞壞」的角度找漏洞。設計 Prompt:「請列出使這個函式出錯的所有極端輸入。」
  2. 狀態機審查:對有狀態轉變的業務(訂單、退款、審核),列出所有狀態,逐一檢查「每個狀態之間」的轉移是否都被定義、是否合法。
  3. 約束極限化:對數量、時間、空間等維度,逐一問「取 0、取 1、取極大值、取負數、取過期」會發生什麼。
  4. 撰寫邊界測試:把每個想到的邊界條件,變成自動化測試(第 5 章)。一旦變成測試,遺漏邊界條件的代價就會被及早發現。

邊界條件與品質#

總結一句話:邊界條件處理得好的系統,是「可靠的」;處理不好的系統,是「碰巧能用的」。 區分成熟軟體與學生作業的,往往正是這些容易被忽略的角落。

從需求階段開始就想邊界條件,比在開發後期補救便宜得多。因此,需求分析師在撰寫需求與驗收條件時,就應該把重要的邊界條件納入考量——這也正是下一節「AI 輔助需求分析」最重要的用途之一。

本章小結#

  • 邊界條件是正常流程之外的特殊情況,最容易出錯也最考驗功力
  • 分類:輸入、時序、狀態、數量四大類
  • 遺漏的根因是只沿著快樂路徑思考
  • AI 擅長補齊通用邊界條件,但業務特定的邊界需要人類深入挖掘
  • 用紅隊思考、狀態機審查、約束極限化、邊界測試來系統性挖掘
  • 好的邊界處理 = 可靠的系統

想一想#

  1. 為「折扣計算」函式列出至少 10 個邊界條件,並為每個定義處理方式。
  2. 你覺得 AI 生成的程式碼,邊界條件處理品質如何?試著實測看看(可以用 OpenCode 見附錄 B)。
  3. 為什麼「一年遇不到一次的罕見問題」往往後果最嚴重?