建立對象的正確姿式?

原創文章&經驗總結&大廠經歷 一路陽光一路滄桑安全

詳情請戳www.codercc.com ui

1. 問題

靜態工廠和構造器有個共同特徵,就是沒法支持多個可選參數。若是構建一個多個可選參數的對象,經常使用的方式有重疊構造器和JavaBean的方式:this

重疊構造器spa

提供一個只有必要參數的構造器,第二個構造器有一個可選參數,第三個構造器有兩個可選參數,依次類推,直到最後一個構造器包含全部的可選參數。線程

缺點:重疊構造器模式在有許多可選參數的時候,代碼可讀性不好,並且調用者想知道每一個參數的意思,甚至須要深刻到源碼中去看每一個參數的意義。若是多個參數的類型相同,調用者顛倒了參數的位置,編譯的時候也不會報錯,就會產生一些微妙的錯誤。設計

JavaBean模式code

經過一個無參構造器建立對象,而後調用setter方法來設置每一個必要的參數。這樣建立實例很容易,產生的代碼讀起來也比較容易,由於經過setter的方法名能知道設置的參數是哪個。cdn

缺點:構造過程被分到了幾個調用之中,在構造過程當中沒法保證JavaBean的一致性,容易出現線程安全的問題。對象

那麼,當構建對象的時候有多個可選參數的時候,應該如何處理?get

2. 答案

在所構建的對象中,有多個可選參數的話,可採用Builder方式來構建對象:

public class User {

private String userName;
private int age;
//可選參數
private String address;
private String phoneNumber;
public static class Builder{
    private String userName;
    private int age;
    //可選參數的默認值
    private String address="";
    private String phoneNumber="";
    public Builder(String userName, int age){
        this.userName = userName;
        this.age = age;
    }
    public Builder address(String address){
        this.address = address;
        return this;
    }
    public Builder phoneNumber(String phoneNumber){
        this.phoneNumber = phoneNumber;
        return this;
    }
    public User build(){
        return new User(this);
    }
}
 private User(Builder builder){
    this.userName = builder.userName;
    this.age = builder.age;
    this.address = builder.address;
    this.phoneNumber = builder.phoneNumber;
 }
複製代碼

} //調用方式 User user = new User.Builder("test",18).address("test").phoneNumber("test").build(); Builder模式能夠對其參數加以約束,build方法能夠檢驗這些約束條件,將參數從builder拷貝到對象中以後,並在對象域而不是builder域中對它們進行檢驗,若是違反了任何約束,build方法就應該拋出IllegalStateException。Builder模式十分靈活,能夠利用單個Builder構建多個對象。惟一的不足在於:爲了建立對象必須先建立一箇中間對象,builder模式還使得構造的過程更加冗長。

3.結論

若是類的構造器或者靜態工廠中具備多個參數時,設計這種類時,Builder模式就是種不錯的選擇,特別是當大多數參數都是可選的時候,與使用傳統的重疊構造器模式項目,使用Builder模式代碼可讀性更強,也比JavaBean的方式更加安全。

相關文章
相關標籤/搜索