先做全局分析,再決定修復順序
三個測試同時失敗——一個是參數不對,另外兩個引用了不存在的事件類別——這時「參數那個比較簡單,先修了再說」是最自然的下一步,而它的依據是修復難度,不是問題結構。
當這幾個症狀出自同一個根因(例如事件系統規劃完整而實作只完成一部分),先修的那一個會在根因被處理後需要再改一次。修復順序的依據要從難度換成結構。
分批思維的陷阱
「分階段處理」本身沒有問題:把大問題切小、每階段有進展,是可行的執行方式。有害的是另一種分批——在完整分析之前就開始決定「先做哪個、後做哪個」。
這種模式的問題在於決策的依據是哪個快,而不是哪個對。它的表現形式通常是:
- 先修復簡單的,再處理複雜的
- 立即解決眼前問題,其他的之後再說
- 邊做邊看,問題浮現了再應對
三者在壓力下都很誘人,因為它們都能讓情況立刻改善一點。代價是同一個位置被反覆修改,總時間高於一次修對,而且每次修改都在系統裡留下一層補丁。
全局分析優先
做法是:發現問題,先停下來分析,再決定怎麼做。
選擇修復路徑之前要先確定幾件事:這個問題影響了哪些檔案與模組、根本原因是什麼(設計就有缺陷,還是實作沒有完成)、有沒有連鎖問題現在看不到而之後會浮現。
判準可以直接執行:影響範圍不明、根因不清楚、發現多個相關問題——符合任何一條就先做完全局分析再動。影響範圍明確且確定是局部問題,才直接修。
策略規劃先行
全局分析之後,下一步是把策略規劃完:把分析中識別出的所有問題都設計進解決方案,拆成可追蹤的任務,標清楚依賴關係,排好執行順序。
這裡有一個關鍵區分:
- 正確的分批執行:有完整策略,所有任務都設計好了,按優先順序一個個做
- 錯誤的分批思維:沒有完整策略,邊做邊規劃,哪個容易先做哪個
兩者的外觀相似——都是一次做一件事——差別在做之前有沒有一張涵蓋全部問題的圖。
策略的完整性用四個問題檢驗:這份策略涵蓋了全局分析識別出的所有問題嗎、每個任務的目標與範圍明確嗎、任務之間的依賴關係清晰嗎、有沒有哪個任務完成之後反而會讓另一個任務需要重做。
設計問題與實作問題要分開
判斷如何處理之前,先分類:這是設計問題,還是實作問題。
設計問題是架構層面的缺陷——違反分層原則、依賴方向錯誤、模組職責不清。共同特徵是:把當下的錯誤修掉之後,架構隱患還在,之後會以另一種形式再出現。
實作問題是設計本身正確,而程式碼還沒寫完或寫錯了:功能規劃完整但程式碼缺失、測試引用的事件類別還沒建立、某個參數傳錯。
兩者的處理方式相反。設計問題要立刻停止功能開發、修正架構,再繼續——繞過去的代價是架構債務會被後續每一個功能繼承。實作問題不需要停,按全局分析的結果規劃任務依序補完即可。
混淆這兩類的其中一個方向特別危險:把設計問題當成實作問題來修,表面上解決了,而問題只是變得更難被看見。
判斷方法直接:這個問題違反了架構原則嗎、影響了多個層級嗎——是的話優先當設計問題處理。問題形態是「功能設計完整但程式碼不在」的,是實作問題。
用開頭那個例子走一次
三個整合測試出錯,表面上是測試引用問題。全局分析之後的結論是:事件系統在早期規劃了完整的事件,實作只完成其中一部分。這是實作問題,不是設計問題。
依此規劃出的策略分三階段:
第一階段補全所有缺失的事件類別。這是其他修改的依賴基礎,必須先做,而這些任務彼此獨立、可以並行。
第二階段在事件類別齊備後統一修復三個測試檔案。這時每個測試的修改都有完整的依賴可以對齊。
第三階段執行所有整合測試確認全數通過,更新文件。
這個順序讓每一步的修改只需要做一次。走「先修簡單的」路線的話,第一個測試會改兩次——一次修參數,一次在其他事件建好之後調整引用。
換成設計問題的例子:一個 UseCase 直接引用了 Widget,違反 Clean Architecture 的分層原則。處理方式是立刻停止其他功能的開發,重新設計 UseCase 的輸入輸出、用 DTO 替代直接引用、修正依賴方向,然後才繼續。這一類繞不過去——依賴方向錯誤會被之後每一個依賴這個 UseCase 的模組沿用。
在壓力下維持這個順序
這套方法論的難處在壓力下的執行:測試出錯、時間緊的時候,「先修了再說」的吸引力最強。
可執行的做法是把判準變成四個要回答的問題——影響範圍確定了嗎、根因清楚嗎、這是設計問題還是實作問題、策略有沒有涵蓋所有識別出的問題。全部答得出來才開始動,有任何一個不確定就繼續分析。
全局分析本身的時間會隨熟練度縮短,而它擋掉的重複修改與架構返工不會隨熟練度減少——這是這個順序長期成立的原因。
同一個問題該由幾個視角同時分析、分歧怎麼收斂,走 多視角並行分析。