前一章已經確認目標系統需要接手的範圍,但功能名稱與程式目錄不足以說明遺留系統(Legacy System)實際如何運作。相同名稱的功能可能包含不同的輸入條件、處理規則與例外情況,看似獨立的功能,也可能修改相同的保存狀態或依賴相同的外部項目。
分析遺留系統時,需要回答下列問題:
這些答案會將「系統有哪些功能」轉換成可供目標系統設計、實作與驗收的分析結果。
分析可以從操作情境、自動觸發條件或其他程式的輸入開始,再逐步回到內部實作。這種順序可以先確認外部需要保留的行為,避免直接按照目錄、類別或函式名稱推測功能目的。
每項功能至少需要記錄下列內容:
| 項目 | 需要確認的問題 |
|---|---|
| 功能目的 | 這項功能要完成甚麼工作,結果由誰或哪個流程使用? |
| 觸發方式 | 功能由人員操作、指定時間、檔案變化、其他程式輸入或甚麼條件啟動? |
| 輸入與前提 | 功能接收哪些內容,執行前需要具備哪些狀態或設定? |
| 主要處理 | 系統依照哪些規則檢查、轉換、計算或分類資料? |
| 輸出 | 系統會回傳、顯示、產生或傳送哪些內容? |
| 狀態變化 | 系統是否新增、修改或刪除保存內容,失敗時會保留甚麼狀態? |
| 外部影響 | 系統是否寫入檔案、呼叫其他程式、發出通知或觸發後續工作? |
| 例外情況 | 輸入不完整、相依項目失效或重複執行時,系統如何處理? |
例如,某套系統包含「匯入資料」功能。只記錄這個名稱,無法判斷目標系統需要保留哪些行為。進一步分析後,可能得到以下描述:
這段描述已經包含觸發、輸入、規則、輸出與狀態變化,也留下重複匯入和處理中斷等需要繼續確認的問題。
功能描述應該維持在可觀察與可驗證的層次。像是「處理資料」或「呼叫共用程式」仍然過於籠統,需要繼續確認處理前後的差異,以及這個呼叫會造成哪些結果。
確認功能情境後,下一步是找出哪些項目共同完成這些功能。每套系統的構成不同,可以按照實際情況確認:
如果系統確實包含前端與後端、資料庫或排程工作,可以直接將它們記錄為已確認的組成項目。無法確認時,先使用「功能入口」、「主要處理」、「資料來源」、「保存狀態」與「相依項目」等中性名稱,等取得足夠資訊後再標示實際技術構成。
| 名詞 | 說明 | 可能包含的內容 |
|---|---|---|
| 操作或自動觸發 | 使系統開始執行某項功能的操作、事件或條件。 | 人員操作、指定時間、檔案變化或其他程式的輸入。 |
| 功能入口 | 系統接收觸發後,開始進入該項功能的程式位置。 | 操作事件的處理位置、自動工作起點、指令處理位置或其他輸入接收位置。 |
| 主要處理 | 系統為了完成該項功能而執行的處理。 | 輸入檢查、格式轉換、規則判斷、計算或狀態變更。 |
| 資料來源 | 系統執行功能時取得待處理內容的地方或管道。資料可以在觸發前已經存在,也可以隨觸發一起傳入。 | 操作輸入、檔案、系統保存內容或其他程式傳入的內容。 |
| 保存狀態 | 系統處理完成後仍會保留,且可能影響後續功能的內容或狀態。 | 處理結果、執行進度、識別資料或功能設定。 |
| 相依項目 | 系統為了建置、啟動或執行功能而依靠的項目。 | 函式庫、套件、執行設定或需要互動的其他程式。 |
系統環境圖可以先呈現觸發來源、系統邊界、資料來源、輸出對象與外部相依,不必在第一版加入所有函式與資料欄位。以下是一個通用示意:

每一條連線都需要補充互動方向、觸發時機、內容格式與失敗影響。例如,只寫「系統連接相依項目」仍無法支持後續設計;記錄「系統在完成輸入檢查後傳送轉換結果,如果傳送失敗就保留待處理狀態」才能說明兩者的實際關係。
系統環境圖呈現整體邊界,呼叫路徑則用來說明單一功能如何穿過各個組成項目。追查時可以按照下列順序進行:
呼叫路徑除了函式名稱,還要記錄各步驟的責任與資料變化。單純列出 A → B → C,後續仍需要重新閱讀程式碼才能知道每一步做了甚麼。較有用的記錄方式是「接收匯入檔案 → 檢查欄位 → 轉換有效資料 → 更新保存狀態 → 產生處理結果」,再於每個步驟補上對應的程式位置與相依項目。
正常完成的路徑只是功能的一部分。輸入不符合格式、相依項目無法使用、處理中斷或相同內容再次執行時,系統可能採用不同路徑。這些分支如果會改變輸出、保存狀態或後續工作,就需要一併記錄。
程式碼中存在的路徑也不一定仍在使用。某段處理可能受執行設定控制、只適用於特定資料,或已經沒有任何入口。是否將它視為現行功能,需要再透過設定、執行紀錄、實際結果或相關人員提供的資訊確認。
功能流程與資料流向需要一起分析。只看呼叫關係,可能知道哪些程式彼此相依,卻看不出欄位意義、狀態變化及外部影響。每一個主要步驟都可以記錄以下資訊:
| 項目 | 記錄內容 |
|---|---|
| 資料來源 | 內容從哪裡取得,由甚麼條件決定讀取範圍? |
| 資料結構 | 有哪些必要欄位、格式、識別方式與關聯? |
| 轉換規則 | 哪些內容會被統一格式、換算、合併、拆分或補上預設值? |
| 狀態變化 | 處理前後有哪些內容不同,變更在哪個時機生效? |
| 輸出內容 | 成功、部分成功與失敗時分別會產生甚麼結果? |
| 外部影響 | 是否產生檔案、通知、執行紀錄或其他程式可觀察的變化? |
欄位名稱相同也可能代表不同意義。例如,兩個功能都使用「狀態」欄位,其中一個把它當成處理階段,另一個把它當成是否可以再次執行的條件。分析時需要記錄欄位在每段流程中的實際用途,不能只依照名稱推定兩者相同。
外部影響也可能發生在主要輸出之外。功能回報失敗時,部分內容可能已經寫入、暫存檔案可能尚未清除,或後續工作可能已被觸發。這些結果會影響目標系統的錯誤處理與驗收條件,因此需要和正常輸出一起記錄。
遺留系統的文件、程式碼與實際行為可能彼此不一致。單一資訊來源只能說明部分情況,需要按照可取得的資料交叉確認。
| 資訊來源 | 可以協助確認的內容 | 需要注意的限制 |
|---|---|---|
| 現有文件 | 原先設計目的、操作步驟、欄位說明與相依關係 | 文件可能過時,也可能只記錄正常流程 |
| 程式碼 | 已實作的條件判斷、資料轉換、呼叫關係與例外處理 | 存在的程式不代表目前仍會執行 |
| 執行紀錄 | 實際發生過的輸入、路徑、錯誤與處理結果 | 紀錄範圍可能不完整,內容也可能經過省略 |
| 保存內容 | 實際資料格式、歷史狀態、特殊值與關聯 | 內容本身不一定能說明形成原因 |
| 實際操作結果 | 特定情境下可觀察的輸入、輸出與狀態變化 | 少量案例不能代表所有分支與邊界條件 |
| 相關人員說明 | 文件未記錄的人工步驟、例外情境與用途 | 記憶可能不完整,需要再以其他資料確認 |
取得資訊後,可以將結論分成三類:
例如,文件寫著空白欄位會使整批匯入失敗,但程式碼中同時存在補上預設值的處理。此時不能直接選擇其中一項作為規格,需要繼續確認執行設定、呼叫路徑與實際結果。確認前,應該記錄兩種可能行為及其影響。
實際操作應該在不影響正式資料與正常運作的條件下進行。如果目前無法建立安全的操作條件,可以先使用既有執行紀錄、受控副本或靜態分析(Static Analysis)結果,並且將無法驗證的部分標示為限制。後續章節會再說明如何建立與正式環境隔離的重構工作環境。
分析結果需要讓後續設計、實作與測試可以直接使用。成果形式可以按照系統規模調整,但至少應該涵蓋以下內容:
| 成果 | 主要內容 |
|---|---|
| 功能規格 | 功能目的、觸發方式、輸入、前提、主要規則、輸出、狀態變化與例外情況 |
| 系統環境圖 | 系統邊界、觸發來源、資料來源、輸出對象、相依項目與人工步驟 |
| 架構圖 | 各組成項目的責任、呼叫方向、共用狀態與相依關係 |
| 功能流程與資料流向 | 關鍵功能的處理順序、條件分支、資料轉換與外部影響 |
| 待確認問題清單 | 問題內容、目前推斷、影響範圍、確認方式、負責人與處理期限 |
圖表用來降低理解關係與流程的成本,不需要追求固定格式。可以使用 Draw.io、 Mermaid、D2 或其他能持續維護的繪圖工具,選擇重點是分析結果能隨確認內容更新。
系統分析可以使用不同圖表描述系統結構、功能、處理流程與組成項目之間的互動。以下舉例四種較常用的圖表,分別呈現架構關係、功能關係、處理流程與互動順序。
文件中的每個項目都應該保留來源或確認方式。例如,功能規格可以連回相關程式位置、執行紀錄、需求決定或操作結果。當程式與文件出現差異時,開發人員才能重新檢查結論,也能知道哪些內容仍需要確認。
本文圖表使用 D2 繪製,並且以 SVG 格式嵌入文章。後續如果改用 Draw.io 或其他能持續維護的工具,可以沿用相同的分析內容重新繪製。
架構圖用來呈現系統的主要組成項目、組成項目之間的連線,以及外部項目如何與系統互動。分析時,可以先列出已確認的組成項目,再按照實際連線補充各項目的責任、互動方向及交換內容。
下圖以包含瀏覽器、反向代理、前端、後端、快取與資料庫的系統為例。瀏覽器與反向代理相連,反向代理分別連接前端與後端,後端再連接快取與資料庫。這張圖只呈現組成項目的連線關係;如果需要記錄執行環境,應該另外補充部署資訊。

使用案例圖用來呈現操作角色、其他程式與系統功能的關係,協助確認誰或甚麼條件會啟動功能,以及各角色預期取得哪些結果。
下圖以具有使用者與管理員兩種角色的系統為例。兩者都能使用登入、查詢與登出功能,管理員另外可以使用編輯功能。這張圖只說明角色與功能的關係,功能內部的處理順序可以使用活動圖或循序圖呈現。

活動圖用來呈現功能從觸發到產生結果的處理順序、條件判斷與分支。
下圖以資料查詢為例,呈現接收請求、輸入查詢條件、判斷是否查詢成功,以及成功或失敗後的處理。查詢成功時會格式化資料,查詢失敗時會產生錯誤狀態碼,最後都會發送回應。

循序圖用來呈現一次功能執行期間,各角色與組成項目按照時間順序發生的互動。它可以補充呼叫方向、傳遞內容、回傳結果與不同條件下的處理差異。
下圖沿用資料查詢的例子,呈現使用者、後端與資料庫之間的互動。使用者發出查詢請求後,後端向資料庫查詢並接收結果;查詢成功時回傳結果,查詢失敗時回傳錯誤狀態碼。

分析工作需要完整理解納入重構範圍的功能、系統規則、資料變化與相依關係,並追查所有會影響這些行為的程式碼。分析深度應該由功能影響與尚未解除的風險決定。納入重構範圍的每項功能至少需要符合下列條件:
範圍外的部分仍需確認是否影響納入範圍的功能、資料或相依關係。確認不會影響目標系統的設計、實作與驗收後,可以不再展開其內部細節。如果仍有關聯,則需要記錄互動方式與影響。後續發現新的入口、隱藏流程或資料依賴時,再更新分析結果與重構範圍。這些成果會持續演進,但每一次設計與實作決定都需要建立在當下已確認的資訊上。