整理 Effective Java 書中 Item 51: Design method signatures 心得筆記

主旨

方法簽名(method signature)是一個方法能否「好用」的第一印象。這篇文章彙整幾個 API 設計小技巧,讓你的方法名稱與參數設計更加清晰、簡潔、可維護,避免常見的地雷與誤用風險。

點出問題:方法設計混亂造成哪些困擾?

常見問題如下:

  • 方法名又臭又長、不知所云
  • 便利方法一堆,反而不知該用哪個
  • 參數超過 4 個,順序一換出 bug
  • 要支援可選參數時手忙腳亂
  • boolean 傳參數,過幾個月根本看不出 true 是什麼意思

這些都會讓 API 難用、難懂、難維護。

劃重點:方法簽名設計五大原則

1. 方法命名要一致好懂

  • 遵守 Java 命名慣例
  • 優先與 package 內的其他命名一致
  • 次要目標是與 Java 標準庫慣用法一致
  • 盡量短,像 size()add()putIfAbsent() 就很清楚
  • 可多參考標準庫方法命名,當靈感來源

2. 不要為了方便加太多方法

  • 每個方法都應該要「值得被加入」
  • 太多方法反而讓使用者選擇困難
  • Interface 特別要注意,會連累實作端

👉 真的常用的情況下再提供簡寫版本(例如常見的 .of().builder()

3. 參數建議不要超過 4 個

  • 參數越多越容易忘記順序
  • 尤其是連續出現同型別參數(如 int, int, int)風險更高

解法一:拆成小方法

範例:List.subList(fromIndex, toIndex) 可以搭配 indexOf(element) 使用,而不需要寫 findFirstIndexInSublist() 這種複合功能的方法。

解法二:用類別包裝參數

如果一堆參數經常一起出現(像 rank, suit),不如包成 Card 類別傳進去。

解法三:使用 Builder pattern

當參數很多又包含選用項時,可用 builder 模式組裝後再呼叫 .build().execute()

4. 參數型別盡量用 interface,而不是具體 class

錯誤做法:

public void process(HashMap<String, String> data);

正確做法:

public void process(Map<String, String> data);

✅ 彈性更大,可以接受 TreeMap、ConcurrentHashMap,甚至是未來的新實作。

5. 不要用 boolean 傳遞選項,改用 enum

例子:

public enum TemperatureScale { FAHRENHEIT, CELSIUS }

Thermometer.newInstance(TemperatureScale.CELSIUS);

👍 可讀性比 newInstance(true) 高太多,也方便未來加 KELVIN 或其他單位。

你也可以把邏輯包進 enum:

public enum TemperatureScale {
    FAHRENHEIT {
        double toCelsius(double t) { return (t - 32) * 5 / 9; }
    },
    CELSIUS {
        double toCelsius(double t) { return t; }
    }
}

小結

設計方法簽名時,請記住這幾個原則:

  • 名字要清楚、短、與慣例一致
  • 參數數量精簡,避免順序混淆
  • 適時使用小物件、builder、或 enum
  • 使用介面作為參數型別,保持彈性
  • 不要濫用 boolean,改用可擴充的 enum

這些技巧能大幅提升 API 的可讀性與可維護性,讓寫的程式不只是能動!