Big Design Up Front 假設能預見所有設計,但實現過程中會不斷遇見意外。敏捷採用「最後可靠時刻」原則:推遲決策直到掌握更多上下文,發現代碼中已成為事實的「慣用模式」,將其提煉為有效抽象。
使用 CKJM 計算 Struts 2 代碼庫兩指標:

單看 WMC 最高的是 DoubleListUIBean (Ca=3),改進收益低。
按 Ca 排序,Component 被 177 類引用,雖複雜度中等,改進連鎖效應巨大。

綜合選 UIBean (WMC=53, Ca=22) 深入分析。
UIBean.evaluateParams() 圈複雜度 43,佔類總複雜度大頭。代碼充滿結構性重複:
if (label != null) { addParameter("label", findString(label)); }
if (labelPosition != null) { addParameter("labelposition", findString(labelPosition)); }
// ... 20+ 同結構塊

命令查找包含 evaluateParams 或 evaluateExtraParams 的類:
find . -name "*.java" | xargs grep -l "void evaluate.*Params"
結果 27 個類(UIBean、TextField、Form、Table 等)皆含此模式。慣用模式浮現:大量 UI 元件需自定義參數處理,各自重複實作。
protected void handleDefaultParameters(String paramName) {
try {
Field f = UIBean.class.getField(paramName);
if (f.get(this) != null) addParameter(paramName, findString(paramName));
} catch (Exception e) { throw new RuntimeException(e); }
}
public void evaluateParams() {
addParameter("templateDir", getTemplateDir());
addParameter("theme", getTheme());
String[] defaultParameters = {"label","labelPosition","requiredPosition", ...};
for (String s : defaultParameters) handleDefaultParameters(s);
}
效果:減少 66 行代碼,圈複雜度降 18 點,未來修改集中在單一方法。
將參數處理機制抽象為獨立類層次,視為 Struts 一等公民,徹底解決橫切關注點。
ThoughtWorks 專案早期需上傳圖片異步化,技術主管拒絕引入消息隊列,採用簡單輪詢。兩年後 3 處異步需求成瓶頸,才引入最簡佇列。因等待「最後可靠時刻」,避免了兩年不必要的複雜度,且對需求理解更深,選型更精準。