模式與反模式的本質差異#

軟體設計中的模式(pattern) 是針對常見問題的有效、可重用解法;反模式(anti-pattern) 則正好相反——它們不一定是團隊故意採用,但長期會讓設計失敗。

模式是已知的最佳實踐,可被廣泛套用;反模式起初看似可行,後續才會顯現負面後果。

簡單對照#

  • 模式:把可在多服務間重用的程式碼模組抽出來解決共同問題
  • 反模式:在程式碼中用 quick fix 解決當下問題,等加新服務時兩個服務一起壞

Spaghetti Code(義大利麵程式)#

如其名,spaghetti code 是缺乏結構的程式碼,常見成因:

  • 在舊程式上不停堆疊新程式,未經規劃
  • 多位開發者在同段程式上反覆 copy-paste 數年
  • 為了趕時程而妥協程式品質
  • 對既有程式做大量 quick fix

Spaghetti code 是「缺乏規劃」與「不遵循標準」的結果。一旦上線後出問題,調查成本極高。

常見成因#

  • 遷移專案時把開發者程式插進舊程式裡
  • 業務需要大量功能,但交付週期一年——程式不斷寫但沒實際使用者驗證,上線時難以追問題
  • 短交付期使開發者犧牲程式碼標準
  • 對龐大程式碼做大量 quick fix

Golden Hammer(金錘)#

過度依賴單一工具來處理多種問題,俗話:「手裡有錘子,看什麼都像釘子」。

有時這種「企業套件包山包海」做法是合理選擇,但若沒有充分評估,就會變成反模式。

常見成因#

  • 組織與單一供應商深度綁定,任何新需求都套用既有工具
  • 開發者沒時間探索其他方案,沿用既有工具
  • 缺乏新需求所需技能,但又不投資招募或培訓

案例:醫療科技平台的雲端瓶頸#

一家醫療科技公司把軟體搬上雲端,兩年內表現良好。後來使用者抱怨效能、QA 也回報多項問題。SRE 與開發協同調查後發現:當前雲端方案無法支撐使用者規模,新加入的大數據報表功能更吃掉一半記憶體。最終把報表功能遷移到擅長大數據的雲端供應商,雖然多了一筆費用,但長期換來可靠性與效能。

教訓:不要用單一解決方案應對所有問題,除非你有充分的決策依據(需求高度吻合、預算或時間有限)。

Boat Anchor(船錨)#

開發者把「未來可能用到」的程式碼留在程式庫中。常見成因:

  • 寫了某需求的程式但需求被取消,程式碼忘了刪
  • 提早完成 6 個月後才要的功能,現在直接放進程式庫
  • 用 toggle 隱藏未來功能,但有人不慎啟用 toggle,導致未測完整的功能上線

不必要的程式碼會增加除錯成本、拖慢編譯、有時甚至直接破壞建置。開發者常無意識引入這個反模式。

Dead Code(死碼)#

執行了卻沒人用其輸出的程式碼。本質上是 boat anchor 的後續產物——舊程式碼留下沒人記得它的功能,但每次編譯都要納入。

常見情境#

  • 過時程式碼從未被刪除,新進開發者意外與其衝突
  • 不再需要的程式碼與其他程式耦合,沒人有把握與時間解耦

案例:金融科技遷雲#

同一家金融科技組織遇到兩個問題:

  • Boat anchor:六個月後才要上的 AI 搜尋功能提前進到 production,雖然 toggle 關閉,但測試環境覆蓋不全,依然影響了正常搜尋功能
  • Dead code:購買股票服務每次觸發 JVM 都會把無用的舊程式一起編進來,導致記憶體吃光而服務失敗

兩者類似但不同:boat anchor 是「為未來而留」,dead code 是「過去用過、現在沒人用」。

God Object(神物件)#

單一物件或類別承擔過多責任,違反物件導向設計的單一職責原則。

拆分後管理彈性遠高於聚合:若 customer ID 同時負責姓名、交易、地址、消費紀錄、未來推薦、優惠等,任何環節變動都波及整體。

常見成因#

  • 開發者習慣擴充既有「萬能物件」,年復一年積累成 god object
  • 拆分需要設計變動與重工,開發者不願承擔

SOLID 原則的呼應#

物件導向裡的 SOLID 原則中第一條 S(Single Responsibility Principle, 單一職責原則) 正是 god object 的解藥:每個類別應有單一職責,便於維護、變更與除錯。

並非所有類別都該嚴格單一職責,但團隊應在「整合」與「拆分」之間取得平衡,並定期審視程式碼以辨識 god object 的萌芽。

Copy and Paste Programming(複製貼上程式設計)#

把其他地方的程式碼直接貼進專案,外觀相似但底層差異常導致問題。

兩段程式縱使解決相同需求,依賴、語言、基礎設施、底層函式庫常常有差異,貼進來後極可能引入隱性 bug。

常見成因#

  • 跨專案搬程式時忽略環境差異,導致 production 環境因函式庫缺失而失敗
  • 為了趕時程,明知有風險仍貼上程式

複製貼上幾乎沒有合理藉口,必須以組織級標準與程式碼審查制度阻止它。

反模式為何重要#

以上所有反模式都會:

  • 拖慢開發進度
  • 引入隱性 bug
  • 影響應用效能
  • 損害程式碼品質

反模式直接傷害可靠性與可用性。SRE 處於開發與運維之間,必須對這些反模式高度敏感,否則維運壓力會持續增加。