首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

演化架構與緊急設計:測試驅動設計(上)——從測後開發到 TDD 的思維轉變

     編輯:Java 相關知識

TDD(測試驅動開發)不僅產出完整單元測試套件,更能將設計決策推遲至「最後負責時刻」,透過測試驅動代碼結構,產生更簡單、可組合、可重用的設計。本文以「完全數查找器」為例,對比「測後開發」與 TDD 兩種流程的設計差異。

TDD 核心工作流:紅-綠-重構

  1. 撰寫一個失敗的測試(紅燈)
  2. 編寫最少代碼讓測試通過(綠燈)
  3. 重構消除重複、提升結構
  4. 循環 1-3,直到無法想出新測試

關鍵差異:「測後開發」先寫代碼再測試,思維已鎖定實作細節;TDD 先寫測試,強迫從使用者視角思考 API 設計,再反推實作。

測後開發版本:直覺導向的陷阱

首版 PerfectNumberFinder1 一次性實作所有邏輯:

public static boolean isPerfect(int number) {
    List<Integer> factors = new ArrayList<>();
    factors.add(1); factors.add(number);
    for (int i = 2; i < number; i++) if (number % i == 0) factors.add(i);
    int sum = 0; for (int n : factors) sum += n;
    return sum - number == number;
}

問題顯而易見:

  • 單一方法承擔過多職責(尋因子、加總、判斷),超過 10 行經驗法則
  • 直覺選用 ArrayList 存因子,實則因子是集合非列表(無序、不重複)
  • 演算法 O(n) 效能差,後續被迫重構為平方根成對法,並手動處理平方數重複

測試只能驗證輸入輸出,無法察覺內部結構缺陷。

TDD 版本:微小步進揭露領域真相

從最簡單問題切入:「判斷數字是否為因子」

@Test public void is_1_a_factor_of_10() { assertTrue(Classifier1.isFactor(1, 10)); }

極簡實作:

public static boolean isFactor(int factor, int number) { return number % factor == 0; }

下一步:「獲取因子列表」,測試驅動 API 設計:

@Test public void factors_for_6() {
    int[] expected = {1, 2, 3, 6};
    Classifier2 c = new Classifier2(6);
    assertThat(c.getFactors(), is(expected));
}

初版實作暴露問題:靜態方法導致參數傳遞繁瑣,轉向實例化設計,將 _number 封裝為欄位。

關鍵洞見:測試揭露錯誤抽象

測試 addFactor() 時失敗:

@Test public void add_factors() {
    Classifier3 c = new Classifier3(6);
    c.addFactor(2); c.addFactor(3);
    assertThat(c.getFactors(), is(Arrays.asList(1, 2, 3, 6))); // 期望有序
}

實際返回 [1, 6, 2, 3]——因建構子預先加入 1 和自身。根因在於:因子本質是集合,而非列表。 改用 Set 瞬時解決順序與去重問題,設計品質躍升。

這正是 TDD 價值:在代碼固化前,測試逼迫你正視領域模型的真實面貌。

組合方法模式的萌芽

重構將 getFactors() 拆解為:

  • 建構子初始化 _factors(含 1、自身)
  • calculateFactors() 迴圈尋因子
  • addFactor() 單一職責添加因子
  • 移除陣列轉換,直接暴露 Set

每個方法單一職責、同一抽象層級,符合 Kent Beck 組合方法模式。

小結與展望

「測後」版本將測試視為驗收門檻;TDD 將測試視為設計探針。下篇將完成 TDD 版本,並以圈複雜度量化優勢,同時探討私有方法測試策略、邊界條件系統性覆蓋等進階主題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved