網頁

2020/6/18

Effective Java 3e - Item 51: Design method signatures carefully 筆記

Effective Java 3e - Item51: Design method signatures carefully 設計方法簽章。

設計方法簽章的通則。

重點:

  • 審慎命名。
  • 不要提供太多類似方法。
  • 避免過長的參數。
  • 參數型態使用介面優於類別。
  • 使用Enum取代boolean。


審慎命名

方法名稱應遵守Java命名慣例。名稱應有意義,容易被他人理解,且整體一致。避免過長的名稱(這點與Clean Code的看法相反),參考Java API或其他主流框架API的命名方式。


不要提供太多捷徑方法。

太多捷徑方法令類別變得難以了解,使用,測試,維護。除非這個捷徑方法常常被使用。


避免過長的參數

參數數量最多不超過四個。太長的參數另方法難以使用且容易因錯置導致錯誤,尤其多個參數型態都相同的時候。

解決參數過長的三個技巧。

  • 切割方法:參數過長可能意味著方法做太多的事 。
  • 參數類別:建立一個類別來包裝參數 。
  • Builder Pattern:使用建造者模式。

例如原本建立使用者的方法要傳入多個參數,修改為利用參數類別及Builder Pattern來減少方法的參數數量。。

public void main() {
    
    String name = "john";
    String password = "123";
    String email = "john@abc.com";
    int age = 40;
    String country = "Taiwan";
    
    createUser(name, password, email, age, country); // 參數過長的方法
    
    CreateUserParams createUserParams = new CreateUserParams();
    createUserParams.setName(name);
    createUserParams.setPassword(password);
    createUserParams.setEmail(email);
    createUserParams.setAge(age);
    createUserParams.setCountry(country);
    
    createUser(createUserParams); // 參數類別
    
    CreateUserParams createUserParamsByBuilder = CreateUserParams.builder() // Builder Pattern
            .name(name).password(password)
            .email(email).age(age)
            .country(country).build();
    
    createUser(createUserParamsByBuilder);
    
}

// 參數過長的方法
public void createUser(String name, String password, String email, int age, String country) {
    // ...
}

// 參數類別
public void createUser(CreateUserParams createUserParams) {
    // ...
}

@Data
@Builder // lombok @Builder annoation
public class CreateUserParams {
    private String name;
    private String password;
    private String email;
    private int age;
    private String country;
    
    public CreateUserParams() {}

    // getter setter
}

參數型態使用介面優於類別

例如參數不要用類別ArrayListHashMap,應改用ListMap。類別參數限制了方法的使用彈性,無法利用繼承及多型帶來的好處。


使用Enum取代boolean

boolean只能呈現兩種狀態,Enum能呈現多種狀態,除了日後擴充比較方便,在語義上也比true/false清楚。

public void main() {
    
    display(true); // boolean
    display(DisplayMode.DARK); // emum
}

public void display(boolean darkMode) {
    // ...
}

public void display(DisplayMode displayMode) {
    // ...
}

public enum DisplayMode {
    NORMAL,
    DARK;
}

沒有留言:

張貼留言