前一章已經選出一項代表性的完整功能,準備用它驗證目標系統的架構與共用基礎。開始實作前,還需要把這項功能在遺留系統中的實際行為轉換成可理解、可確認的規則。否則,即使目標程式的結構更清楚,也可能因為遺漏條件分支、預設值或失敗後的狀態而產生不同結果。
第 4 章已經從整體範圍說明如何確認系統邊界、組成項目與功能流程。本章進一步聚焦於單一功能,說明如何從入口點追查程式碼,找出影響結果的判斷、資料變化與例外處理,再將分析結果整理成目標系統可以實作與驗證的規格。
分析前要先定義功能的起點與終點。功能名稱可能對應多條執行路徑,同一條路徑也可能按照輸入或執行設定產生不同結果。如果只用畫面名稱、程式目錄或類別名稱界定範圍,很容易把不相關的程式一起納入,或漏掉實際會改變結果的處理。
可以先記錄下列資訊:
| 項目 | 需要確認的內容 |
|---|---|
| 使用情境 | 這項功能要完成甚麼工作,由甚麼操作、事件或條件觸發? |
| 功能入口 | 哪一段程式最先接收輸入或開始執行? |
| 輸入與前提 | 功能接收哪些內容,執行前需要具備哪些設定或狀態? |
| 完成結果 | 成功、拒絕處理、部分完成與失敗時,各自會產生甚麼結果? |
| 狀態變化 | 功能會新增、修改或刪除哪些保存內容,變更在甚麼時機生效? |
| 外部影響 | 功能是否產生檔案、通知、執行紀錄,或觸發其他程式? |
| 相依項目 | 哪些組成項目、函式庫、設定或其他程式會影響執行結果? |
例如,分析「匯入資料」時,可以把起點定義為系統接收指定格式的檔案,終點則是產生匯入結果並完成必要的狀態變更。檔案如何上傳、由人員選取,或由自動工作取得,要按照系統實際情況記錄。這樣才能在不預設特定操作方式的前提下,明確限制本次需要追查的路徑。
如果同一入口會進入多項功能,應該先找出用來分流的輸入、設定或狀態。如果同一功能具有多個入口,則要分別記錄各入口提供的資料與前置處理,再確認它們從哪個位置開始共用相同規則。
入口點是追查程式碼的起點。依照系統實際構成,入口可能是操作事件、指令、自動工作、檔案變化、訊息,或其他程式傳入的內容。找到入口後,不要只閱讀名稱看似相關的檔案,而要沿著實際呼叫關係確認資料如何進入、改變及離開系統。
追查時可以按照下列順序進行:
程式碼搜尋、尋找參照與靜態分析(Static Analysis)可以協助找出可能的呼叫關係,但搜尋結果只能表示程式之間存在連結。某段程式是否真的執行,仍要確認入口、設定、條件分支與目前使用的版本。沒有任何現行入口的程式可以先標示為待確認,不能直接當成目標系統需要保留的功能。
如果遺留程式碼的呼叫層次很深,可以先記錄主要路徑,再逐步展開會影響輸入、輸出或狀態的部分。單純轉交參數、沒有改變結果的內部細節,可以保留程式位置,不必在第一輪分析逐行說明。
看懂呼叫順序仍不足以還原功能規則。真正需要保留或重新決定的內容,通常藏在條件分支、預設值、資料轉換、狀態判斷與例外處理中。分析每個主要步驟時,可以持續詢問:「甚麼條件會讓結果不同?」
需要特別注意的程式內容包含:
以下表格可以把程式細節轉換成功能規則:
| 程式觀察 | 需要確認的問題 | 規則記錄方式 |
|---|---|---|
| 條件分支 | 哪些輸入或狀態會進入這個分支? | 記錄條件、採取的處理及可觀察結果。 |
| 預設值 | 預設值在甚麼情況下套用,來源是否固定? | 記錄套用條件、實際值及對後續處理的影響。 |
| 資料轉換 | 轉換前後的格式、精度或意義有甚麼差異? | 記錄輸入範例、轉換規則及輸出範例。 |
| 狀態變更 | 何時變更、失敗時是否保留,以及後續功能如何使用? | 記錄前置狀態、觸發條件、結果狀態及失敗狀態。 |
| 例外處理 | 哪些錯誤會被攔截,呼叫端最後收到甚麼結果? | 記錄錯誤來源、處理方式、輸出及已產生的影響。 |
| 外部互動 | 呼叫失敗、逾時或回傳不完整內容時如何處理? | 記錄呼叫條件、交換內容、失敗路徑及重新執行條件。 |
分析狀態變化時,不要只記錄變數最後的值。還要說明值在甚麼條件下改變,以及這項變化會影響哪些後續判斷。對於容易混淆的流程,可以建立狀態表,將每一個步驟的輸入狀態、判斷條件、執行動作與結果狀態分開記錄。
| 步驟 | 輸入狀態 | 判斷條件 | 執行動作 | 結果狀態 |
|---|---|---|---|---|
| 接收內容 | 尚未處理 | 必要欄位完整 | 統一內容格式 | 等待檢查 |
| 檢查內容 | 等待檢查 | 內容符合規則 | 執行主要處理 | 處理中 |
| 檢查內容 | 等待檢查 | 內容不符合規則 | 記錄失敗原因 | 已拒絕 |
| 完成處理 | 處理中 | 所有必要步驟完成 | 產生處理結果 | 已完成 |
表格中的名稱只是示意。實際分析時,要使用系統已確認的狀態與結果,不能為了填滿表格而自行補上不存在的階段。
程式命名可以協助判斷可能的責任,但名稱可能過於簡略,也可能在多次修改後失去原意。像是 validate、process 或 status 只能提示程式可能在檢查、處理或保存狀態,無法說明具體條件與結果。分析時要回到實際讀取、判斷與寫入的內容,不應該直接把名稱改寫成功能規格。
註解可以說明設計原因、歷史限制或特殊處理,但註解不一定會隨程式更新。畫面文字、翻譯內容與錯誤訊息通常更接近操作人員能觀察的結果,仍可能只涵蓋部分分支。每一種資訊都適合作為追查線索,需要再和目前程式及執行結果交叉確認。
| 資訊來源 | 可以提供的線索 | 需要確認的限制 |
|---|---|---|
| 程式命名 | 組成項目、函式與變數原先預期的責任 | 名稱可能含糊、過時或與實際行為不同。 |
| 程式註解 | 設計原因、特殊限制與歷史相容需求 | 註解可能沒有隨程式修改。 |
| 可見文字 | 操作流程、欄位意義、錯誤情境與可觀察結果 | 文字不一定涵蓋內部狀態與所有例外。 |
| 執行設定 | 功能是否啟用、分支條件與相依項目選擇 | 不同執行環境可能使用不同設定。 |
| 執行紀錄 | 實際出現的路徑、輸入特徵、錯誤與處理結果 | 紀錄可能不完整,也可能沒有保存必要欄位。 |
當不同來源互相矛盾時,應該保留差異與確認方式。例如,註解表示空白內容應該被拒絕,但目前程式會補上預設值,就要確認這個分支是否仍會執行、實際結果是甚麼,以及哪一種行為符合目前需求。在完成確認前,不能任選其中一項作為目標規格。
靜態閱讀可以找出可能路徑,卻不一定能確認執行時採用的設定、資料內容與分支。只要已經具備不影響正式運作的獨立環境,就可以用受控輸入執行功能,觀察程式實際經過的位置與產生的結果。
確認時可以採用下列做法:
加入觀察用程式碼時,要避免改變原有執行順序、例外處理或資料內容。正式環境如果沒有安全的觀察方式,應該優先使用既有紀錄或受控副本,不應該為了分析而直接執行可能改變正式狀態的操作。
執行紀錄也不能單獨代表完整規則。某個分支在選定期間沒有出現,可能是使用頻率低、紀錄範圍不足,或觸發條件已經不存在。分析結果應該說明觀察範圍與限制,並且把尚未執行確認的路徑標示出來。
遺留系統目前會產生的結果,不一定都要原樣帶入目標系統。某些行為是明確的功能規則,某些是長期存在但已知不正確的結果,也可能是為了相容既有資料或外部項目而保留的處理。分析階段要先描述實際行為,再確認它在目標系統中的處理方式。
可以將發現的行為分成四類:
| 分類 | 判斷方式 | 後續處理 |
|---|---|---|
| 預期規則 | 行為符合目前需求,相關輸入與結果已經確認。 | 將規則納入目標功能規格與驗收條件。 |
| 已知錯誤 | 行為會產生不符合需求的結果,而且修正方向已經確認。 | 記錄既有結果、目標結果及受影響範圍。 |
| 歷史相容行為 | 行為用來支援既有資料格式、操作方式或相依項目。 | 確認相容對象是否仍存在,再決定保留、轉換或移除。 |
| 待確認行為 | 現有資料不足,或不同資訊來源提出不同解釋。 | 記錄可能結果、影響與確認方式,暫不寫成確定規則。 |
分類不能只由程式實作決定。已知錯誤是否在目標系統修正、相容行為是否仍需保留,以及需求差異如何驗收,都需要由適當的需求決策者確認。分析文件則要留下實際行為、決定結果與適用範圍,讓實作人員知道哪些差異是預定變更。
程式碼可以說明目前如何執行,卻無法完整說明為甚麼需要這項功能、哪一種結果才符合目前需求,或某段特殊處理是否仍有使用情境。遇到這些問題時,需要向了解實際操作、需求決定或維護歷史的人員確認。
詢問時應該帶著具體情境與已知結果,避免只問「這段程式在做甚麼」。例如,可以提供一組輸入、目前程式會採取的分支及產生的結果,再確認:
口頭說明仍需要和程式、執行結果或其他可取得的資訊互相確認。如果不同人員的說法不一致,應該記錄差異、適用情境與最後決定,不能把其中一種說法直接視為通用規則。
呼叫層次較深或互動項目較多時,可以使用循序圖(Sequence Diagram)記錄一次功能執行中的呼叫順序、傳遞內容與回傳結果。圖中應該使用具有功能意義的動作,例如「檢查輸入」、「取得目前狀態」與「保存處理結果」,避免只排列類別或函式名稱。條件分支與失敗路徑可以分開呈現,讓讀者能看出不同條件造成的互動差異。
循序圖適合呈現互動順序,狀態表適合呈現資料或變數如何改變,規則表則適合整理條件與結果。三者不需要重複記錄所有細節,可以按照問題選擇合適形式:
| 分析問題 | 合適的記錄方式 |
|---|---|
| 哪些組成項目按照甚麼順序互動? | 使用循序圖記錄參與項目、呼叫內容、回傳結果與失敗路徑。 |
| 某項狀態如何隨處理步驟改變? | 使用狀態表記錄前置狀態、觸發條件、執行動作與結果狀態。 |
| 多個條件如何共同決定結果? | 使用規則表列出條件組合、處理方式與預期結果。 |
| 結論來自哪裡,是否已經確認? | 在分析紀錄中標示程式位置、執行結果、相關說明與確認狀態。 |
圖表與表格都要連回實際程式位置或確認來源。程式修改或需求決定改變時,也要同步更新分析結果,避免文件再次成為過時線索。
完成路徑追查後,要把散落在程式中的判斷整理成目標系統可以使用的功能規格。每一項規則至少要包含:
整理時可以按照責任將內容分成輸入處理、功能規則、狀態讀寫、外部互動、輸出轉換及例外處理。這項分類用來釐清行為,不代表目標系統一定要建立相同數量的類別或模組。介面(Interface)、類別(Class)或共用元件要如何設計,仍需按照目標架構、相依方向與實際重複需求決定。
外觀相似的程式也不一定代表相同規則。只有當多條路徑的功能目的、輸入意義、變更原因與預期結果一致時,才適合考慮共用抽象。分析階段如果太早合併名稱相似的邏輯,可能會隱藏不同功能之間的重要差異。
規格中的範例會成為後續測試案例的基礎。至少要涵蓋主要正常路徑、邊界條件、輸入不完整、重複執行、相依項目失敗,以及已確認需要保留的歷史相容行為。後續章節會再說明如何用這些案例比較遺留系統與目標系統的結果。
開始實作目標功能前,可以用下列問題檢查分析結果是否足夠:
如果某項問題仍會影響目標系統的設計、實作或驗收,就應該保留為明確的待確認項目。無法立即取得答案不代表可以自行推定,應該記錄目前已知範圍及確認後需要更新的內容。