iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0

如何從遺留程式碼找出功能規則?

前一章已經選出一項代表性的完整功能,準備用它驗證目標系統的架構與共用基礎。開始實作前,還需要把這項功能在遺留系統中的實際行為轉換成可理解、可確認的規則。否則,即使目標程式的結構更清楚,也可能因為遺漏條件分支、預設值或失敗後的狀態而產生不同結果。

第 4 章已經從整體範圍說明如何確認系統邊界、組成項目與功能流程。本章進一步聚焦於單一功能,說明如何從入口點追查程式碼,找出影響結果的判斷、資料變化與例外處理,再將分析結果整理成目標系統可以實作與驗證的規格。

先界定要分析的功能路徑

分析前要先定義功能的起點與終點。功能名稱可能對應多條執行路徑,同一條路徑也可能按照輸入或執行設定產生不同結果。如果只用畫面名稱、程式目錄或類別名稱界定範圍,很容易把不相關的程式一起納入,或漏掉實際會改變結果的處理。

可以先記錄下列資訊:

項目 需要確認的內容
使用情境 這項功能要完成甚麼工作,由甚麼操作、事件或條件觸發?
功能入口 哪一段程式最先接收輸入或開始執行?
輸入與前提 功能接收哪些內容,執行前需要具備哪些設定或狀態?
完成結果 成功、拒絕處理、部分完成與失敗時,各自會產生甚麼結果?
狀態變化 功能會新增、修改或刪除哪些保存內容,變更在甚麼時機生效?
外部影響 功能是否產生檔案、通知、執行紀錄,或觸發其他程式?
相依項目 哪些組成項目、函式庫、設定或其他程式會影響執行結果?

例如,分析「匯入資料」時,可以把起點定義為系統接收指定格式的檔案,終點則是產生匯入結果並完成必要的狀態變更。檔案如何上傳、由人員選取,或由自動工作取得,要按照系統實際情況記錄。這樣才能在不預設特定操作方式的前提下,明確限制本次需要追查的路徑。

如果同一入口會進入多項功能,應該先找出用來分流的輸入、設定或狀態。如果同一功能具有多個入口,則要分別記錄各入口提供的資料與前置處理,再確認它們從哪個位置開始共用相同規則。

從入口點追查實際執行路徑

入口點是追查程式碼的起點。依照系統實際構成,入口可能是操作事件、指令、自動工作、檔案變化、訊息,或其他程式傳入的內容。找到入口後,不要只閱讀名稱看似相關的檔案,而要沿著實際呼叫關係確認資料如何進入、改變及離開系統。

追查時可以按照下列順序進行:

  1. 找出入口的註冊位置與觸發條件,確認目前執行設定確實會啟用這條路徑。
  2. 記錄入口接收的原始輸入,以及進入主要處理前的格式統一、預設值與拒絕條件。
  3. 追蹤每一次函式或組成項目呼叫,說明它會讀取、判斷、轉換或修改甚麼內容。
  4. 找出所有會改變執行方向的條件分支,包括提前結束、略過處理、重新嘗試及例外處理。
  5. 標示保存狀態與外部影響發生的位置,確認失敗時是否已經產生部分結果。
  6. 追到呼叫端能觀察的輸出或最終狀態,確認整條路徑已經閉合。

程式碼搜尋、尋找參照與靜態分析(Static Analysis)可以協助找出可能的呼叫關係,但搜尋結果只能表示程式之間存在連結。某段程式是否真的執行,仍要確認入口、設定、條件分支與目前使用的版本。沒有任何現行入口的程式可以先標示為待確認,不能直接當成目標系統需要保留的功能。

如果遺留程式碼的呼叫層次很深,可以先記錄主要路徑,再逐步展開會影響輸入、輸出或狀態的部分。單純轉交參數、沒有改變結果的內部細節,可以保留程式位置,不必在第一輪分析逐行說明。

記錄每個判斷造成的結果差異

看懂呼叫順序仍不足以還原功能規則。真正需要保留或重新決定的內容,通常藏在條件分支、預設值、資料轉換、狀態判斷與例外處理中。分析每個主要步驟時,可以持續詢問:「甚麼條件會讓結果不同?」

需要特別注意的程式內容包含:

  • 條件判斷會接受、拒絕、略過或改變哪些輸入。
  • 缺少欄位或設定時,程式會補上甚麼預設值。
  • 資料在比較或計算前,是否經過格式統一、換算、排序或合併。
  • 目前保存狀態如何影響下一步,以及功能完成後會變成甚麼狀態。
  • 多個條件同時成立時,程式採用哪一項規則,以及判斷順序是否會改變結果。
  • 發生例外時,程式會停止、略過、重新嘗試、保留部分結果,或改用替代路徑。
  • 相同輸入重複執行時,系統會產生相同結果、更新既有內容,或產生另一份內容。

以下表格可以把程式細節轉換成功能規則:

程式觀察 需要確認的問題 規則記錄方式
條件分支 哪些輸入或狀態會進入這個分支? 記錄條件、採取的處理及可觀察結果。
預設值 預設值在甚麼情況下套用,來源是否固定? 記錄套用條件、實際值及對後續處理的影響。
資料轉換 轉換前後的格式、精度或意義有甚麼差異? 記錄輸入範例、轉換規則及輸出範例。
狀態變更 何時變更、失敗時是否保留,以及後續功能如何使用? 記錄前置狀態、觸發條件、結果狀態及失敗狀態。
例外處理 哪些錯誤會被攔截,呼叫端最後收到甚麼結果? 記錄錯誤來源、處理方式、輸出及已產生的影響。
外部互動 呼叫失敗、逾時或回傳不完整內容時如何處理? 記錄呼叫條件、交換內容、失敗路徑及重新執行條件。

分析狀態變化時,不要只記錄變數最後的值。還要說明值在甚麼條件下改變,以及這項變化會影響哪些後續判斷。對於容易混淆的流程,可以建立狀態表,將每一個步驟的輸入狀態、判斷條件、執行動作與結果狀態分開記錄。

步驟 輸入狀態 判斷條件 執行動作 結果狀態
接收內容 尚未處理 必要欄位完整 統一內容格式 等待檢查
檢查內容 等待檢查 內容符合規則 執行主要處理 處理中
檢查內容 等待檢查 內容不符合規則 記錄失敗原因 已拒絕
完成處理 處理中 所有必要步驟完成 產生處理結果 已完成

表格中的名稱只是示意。實際分析時,要使用系統已確認的狀態與結果,不能為了填滿表格而自行補上不存在的階段。

將命名、註解與可見文字當成線索

程式命名可以協助判斷可能的責任,但名稱可能過於簡略,也可能在多次修改後失去原意。像是 validateprocessstatus 只能提示程式可能在檢查、處理或保存狀態,無法說明具體條件與結果。分析時要回到實際讀取、判斷與寫入的內容,不應該直接把名稱改寫成功能規格。

註解可以說明設計原因、歷史限制或特殊處理,但註解不一定會隨程式更新。畫面文字、翻譯內容與錯誤訊息通常更接近操作人員能觀察的結果,仍可能只涵蓋部分分支。每一種資訊都適合作為追查線索,需要再和目前程式及執行結果交叉確認。

資訊來源 可以提供的線索 需要確認的限制
程式命名 組成項目、函式與變數原先預期的責任 名稱可能含糊、過時或與實際行為不同。
程式註解 設計原因、特殊限制與歷史相容需求 註解可能沒有隨程式修改。
可見文字 操作流程、欄位意義、錯誤情境與可觀察結果 文字不一定涵蓋內部狀態與所有例外。
執行設定 功能是否啟用、分支條件與相依項目選擇 不同執行環境可能使用不同設定。
執行紀錄 實際出現的路徑、輸入特徵、錯誤與處理結果 紀錄可能不完整,也可能沒有保存必要欄位。

當不同來源互相矛盾時,應該保留差異與確認方式。例如,註解表示空白內容應該被拒絕,但目前程式會補上預設值,就要確認這個分支是否仍會執行、實際結果是甚麼,以及哪一種行為符合目前需求。在完成確認前,不能任選其中一項作為目標規格。

用受控執行確認程式推論

靜態閱讀可以找出可能路徑,卻不一定能確認執行時採用的設定、資料內容與分支。只要已經具備不影響正式運作的獨立環境,就可以用受控輸入執行功能,觀察程式實際經過的位置與產生的結果。

確認時可以採用下列做法:

  1. 準備一組能重複建立的輸入與初始狀態,先記錄預期會進入的路徑。
  2. 使用除錯工具、暫時性的執行紀錄或其他觀察方式,確認條件值、呼叫順序與狀態變化。
  3. 改變一項輸入或前置狀態,觀察結果差異是否符合程式推論。
  4. 對正常、邊界、缺少內容、重複執行及相依項目失敗等情況分別記錄結果。
  5. 執行完成後檢查主要輸出、保存狀態與外部影響,避免只根據畫面或回傳內容判斷。

加入觀察用程式碼時,要避免改變原有執行順序、例外處理或資料內容。正式環境如果沒有安全的觀察方式,應該優先使用既有紀錄或受控副本,不應該為了分析而直接執行可能改變正式狀態的操作。

執行紀錄也不能單獨代表完整規則。某個分支在選定期間沒有出現,可能是使用頻率低、紀錄範圍不足,或觸發條件已經不存在。分析結果應該說明觀察範圍與限制,並且把尚未執行確認的路徑標示出來。

區分規則、錯誤與相容行為

遺留系統目前會產生的結果,不一定都要原樣帶入目標系統。某些行為是明確的功能規則,某些是長期存在但已知不正確的結果,也可能是為了相容既有資料或外部項目而保留的處理。分析階段要先描述實際行為,再確認它在目標系統中的處理方式。

可以將發現的行為分成四類:

分類 判斷方式 後續處理
預期規則 行為符合目前需求,相關輸入與結果已經確認。 將規則納入目標功能規格與驗收條件。
已知錯誤 行為會產生不符合需求的結果,而且修正方向已經確認。 記錄既有結果、目標結果及受影響範圍。
歷史相容行為 行為用來支援既有資料格式、操作方式或相依項目。 確認相容對象是否仍存在,再決定保留、轉換或移除。
待確認行為 現有資料不足,或不同資訊來源提出不同解釋。 記錄可能結果、影響與確認方式,暫不寫成確定規則。

分類不能只由程式實作決定。已知錯誤是否在目標系統修正、相容行為是否仍需保留,以及需求差異如何驗收,都需要由適當的需求決策者確認。分析文件則要留下實際行為、決定結果與適用範圍,讓實作人員知道哪些差異是預定變更。

向相關人員確認程式無法回答的問題

程式碼可以說明目前如何執行,卻無法完整說明為甚麼需要這項功能、哪一種結果才符合目前需求,或某段特殊處理是否仍有使用情境。遇到這些問題時,需要向了解實際操作、需求決定或維護歷史的人員確認。

詢問時應該帶著具體情境與已知結果,避免只問「這段程式在做甚麼」。例如,可以提供一組輸入、目前程式會採取的分支及產生的結果,再確認:

  • 這個結果是否符合目前需求,哪些情況允許例外?
  • 操作人員遇到失敗時,實際會如何判斷與處理?
  • 是否存在程式外的人工步驟、前置準備或後續修正?
  • 這項特殊處理目前仍支援哪些資料、操作方式或相依項目?
  • 如果目標系統採用不同結果,哪些流程、資料或相關人員會受影響?

口頭說明仍需要和程式、執行結果或其他可取得的資訊互相確認。如果不同人員的說法不一致,應該記錄差異、適用情境與最後決定,不能把其中一種說法直接視為通用規則。

用循序圖與規則表保存分析結果

呼叫層次較深或互動項目較多時,可以使用循序圖(Sequence Diagram)記錄一次功能執行中的呼叫順序、傳遞內容與回傳結果。圖中應該使用具有功能意義的動作,例如「檢查輸入」、「取得目前狀態」與「保存處理結果」,避免只排列類別或函式名稱。條件分支與失敗路徑可以分開呈現,讓讀者能看出不同條件造成的互動差異。

循序圖適合呈現互動順序,狀態表適合呈現資料或變數如何改變,規則表則適合整理條件與結果。三者不需要重複記錄所有細節,可以按照問題選擇合適形式:

分析問題 合適的記錄方式
哪些組成項目按照甚麼順序互動? 使用循序圖記錄參與項目、呼叫內容、回傳結果與失敗路徑。
某項狀態如何隨處理步驟改變? 使用狀態表記錄前置狀態、觸發條件、執行動作與結果狀態。
多個條件如何共同決定結果? 使用規則表列出條件組合、處理方式與預期結果。
結論來自哪裡,是否已經確認? 在分析紀錄中標示程式位置、執行結果、相關說明與確認狀態。

圖表與表格都要連回實際程式位置或確認來源。程式修改或需求決定改變時,也要同步更新分析結果,避免文件再次成為過時線索。

將發現轉換成可實作的規格

完成路徑追查後,要把散落在程式中的判斷整理成目標系統可以使用的功能規格。每一項規則至少要包含:

  • 規則適用的功能情境與觸發條件。
  • 需要的輸入、前置狀態及相關設定。
  • 系統採取判斷或轉換的明確條件。
  • 正常、拒絕處理與失敗時的輸出及狀態變化。
  • 規則的程式位置、確認方式與目前確認狀態。
  • 目標系統要保留、調整或移除這項行為的決定。
  • 可以驗證這項規則的輸入範例與預期結果。

整理時可以按照責任將內容分成輸入處理、功能規則、狀態讀寫、外部互動、輸出轉換及例外處理。這項分類用來釐清行為,不代表目標系統一定要建立相同數量的類別或模組。介面(Interface)、類別(Class)或共用元件要如何設計,仍需按照目標架構、相依方向與實際重複需求決定。

外觀相似的程式也不一定代表相同規則。只有當多條路徑的功能目的、輸入意義、變更原因與預期結果一致時,才適合考慮共用抽象。分析階段如果太早合併名稱相似的邏輯,可能會隱藏不同功能之間的重要差異。

規格中的範例會成為後續測試案例的基礎。至少要涵蓋主要正常路徑、邊界條件、輸入不完整、重複執行、相依項目失敗,以及已確認需要保留的歷史相容行為。後續章節會再說明如何用這些案例比較遺留系統與目標系統的結果。

完成分析前的檢查

開始實作目標功能前,可以用下列問題檢查分析結果是否足夠:

  • 是否已經界定功能的入口、完成結果及本次分析範圍?
  • 是否追到所有會改變輸出、保存狀態與外部影響的主要路徑?
  • 是否找到影響結果的條件分支、預設值、轉換規則與判斷順序?
  • 是否確認失敗、部分完成與重複執行時會留下甚麼結果?
  • 是否用受控執行或其他資訊確認主要程式推論?
  • 是否區分預期規則、已知錯誤、歷史相容行為與待確認行為?
  • 是否記錄程式無法回答的問題、影響範圍與確認方式?
  • 是否已將主要規則轉換成具有輸入條件、預期結果與確認狀態的規格?

如果某項問題仍會影響目標系統的設計、實作或驗收,就應該保留為明確的待確認項目。無法立即取得答案不代表可以自行推定,應該記錄目前已知範圍及確認後需要更新的內容。

重點整理

  • 分析單一功能前,需要先界定入口、輸入、完成結果、狀態變化、外部影響與相依項目。
  • 從入口點沿著實際呼叫關係追查時,要特別記錄會改變結果的條件分支、預設值、資料轉換、狀態判斷與例外處理。
  • 程式命名、註解、可見文字、執行設定與執行紀錄都只能提供部分線索,需要和目前程式及受控執行結果交叉確認。
  • 遺留系統的實際行為要區分為預期規則、已知錯誤、歷史相容行為與待確認行為,再決定目標系統如何處理。
  • 循序圖、狀態表與規則表可以分別記錄互動順序、狀態變化及條件結果,並且連回實際程式位置與確認來源。
  • 分析結果要轉換成包含適用情境、輸入條件、處理規則、預期結果、確認狀態與測試範例的功能規格。

上一篇
[Day 13] 應該從哪裡開始重構遺留系統?
系列文
遠古聖遺物改造工程:遺留系統全面重構實務指南14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言