路徑 02課程 5 / 6

安全地修改既有系統

導入變更時,保留現有契約,並考慮舊用戶端、資料與部署順序。

進階11 分鐘已審查

發布者 我們如何撰寫

檢查理解程度你在同一次發布中重新命名資料庫欄位,並更新應用程式。還可能出什麼問題?進行練習
你在同一次發布中重新命名資料庫欄位,並更新應用程式。還可能出什麼問題?

學習目標

  • 辨識局部程式碼變更可能影響的契約。
  • 解釋分階段擴充再收縮的變更方式。
  • 區分程式碼回復與資料復原。

找出變更周圍的契約

既有軟體有呼叫端、儲存資料、排程工作和維運程序。部分相依關係,無法從想編輯的檔案中看見。代理程式可能產生局部正確的變更,卻破壞其中一項契約。

實作前,找出受影響資料的讀取端與寫入端。檢查路由、背景工作、報表和外部整合,確認其他團隊或較舊用戶端版本,是否依賴目前行為。

請代理程式提供這份相依關係圖的證據。搜尋結果是有用起點,但動態呼叫和外部使用方,可能需要負責人確認。

讓目前行為可被觀察

對文件不足的模組,針對必須穩定的行為加入聚焦檢查。這些檢查描述目前契約,不代表所有既有行為都值得保留。

如果目前行為與需求衝突,記錄衝突。不要只因測試捕捉到某個資安缺陷,就保留它。取得必要決定,區分預期行為和缺陷。

使用貼近實際、但不含敏感資訊的測試資料。可能出現舊資料結構和不完整紀錄時,也應納入。新的資料結構描述若只用新建資料測試,可能掩蓋移轉問題。

審查版本間的過渡

以將 customer_name 改名為 display_name 的虛構情境為例。立即改名,可能在部署期間破壞舊應用程式執行個體。同一個 pull request 修改兩個檔案,不代表部署具有不可分割性。

分階段做法可以維持相容:

  1. 新增欄位,先不移除舊欄位。
  2. 定義新的寫入如何保持必要值一致。
  3. 使用可重新啟動的程序,補填既有紀錄。
  4. 驗證完整性與讀取端行為。
  5. 將讀取端移至新欄位。
  6. 只有所有使用方都不再依賴舊欄位時,才移除它。

具體方法取決於資料庫與寫入模式。如果其中一次寫入失敗,雙重寫入可能造成不一致。可能需要資料庫交易,或其他明確同步方式。檢查系統保證前,不要直接套用這個範例。

Martin Fowler 將這種一般過渡方式稱為 parallel change,也稱 expand-and-contract。核心是在移除前,先建立相容的過渡過程。

分開規劃復原與版本回復

程式碼回復會還原較早的應用程式版本,但不會自動撤銷資料移轉。舊版本可能無法理解新資料。破壞性移轉可能移除資訊,而回復程式碼無法找回這些資訊。

為每一步找出復原操作。可重新啟動的補填程序,可能能安全續行。錯誤轉換可能需要依保留的來源資料修正。破壞性操作則可能需要已驗證的還原程序。

確認誰負責復原決策,以及可能需要多久。不要把「我們有備份」當作復原符合服務要求的證據。

讓變更可供審查

將不相關清理與功能變更分開。在 pull request 提供相容計畫、驗證結果和移除條件,標出哪個步驟之後,回復需要額外工作。

代理程式能協助檢查使用方、準備移轉程式碼,但負責人仍須接受過渡與復原計畫。最終設計只是安全變更的一部分。

進行練習

選擇一項小型欄位或 API 變更。列出所有讀取端與寫入端,包括背景工作。描述先新增的步驟、過渡檢查及移除條件,並找出哪一步可能讓回復變得不可行。

下載工作表(Markdown)
檢查理解程度 ↑

繼續學習

來源與延伸閱讀

Taiga 相關延伸閱讀

← 上一課: 審查 AI 生成的程式碼