1. 程式人生 > >Builder設計模式

Builder設計模式

函數 tid ace 這就是 row 變量 線程安全 uil public

Builder模式

創建一個entity或者javabean通常使用三種方法。

  • 使用無參構造函數,用setter方法來設置對象的初始值。
  • 使用帶參構造函數,通過構造函數來初始化參數
  • 使用builder設計模式創建對象。

如果使用常用的getter/setter方法,那麽通常在構造一個我們需要的對象時,使用一長串的setter方法,並且該對象也變成是可變的,即可以使用setter方法隨意的修改對象的狀態。

使用帶參構造函數能夠避免創建可變的對象,但是需要大量的構造函數,要想考慮到每一種情況,構造函數的數量需要用排練組合來計算,或者是創建一個包含全部參數的構造函數,當我們不關註該對象的某個屬性時,通過給它設置個默認值即可,通常是null,0,false等。但是當存在大量的參數時,會出現很難把值與變量的位置匹配起來,給閱讀與書寫帶來大量的麻煩。

為了避免上述的情況,我們可以使用builder模式來創建一個java對象。主要是利用靜態內部類的方式。

見代碼如下:

package com.manager.design;

public class Student2 {
private final int id;
private final String name;
private int age;

private Student2(){}   //定義私有構造器,只能在類內部使用(提供給靜態內部類創建一個對象)

private Student2(Student2 origin){  // 拷貝一個對象,即把靜態內部類對象的屬性給外部類,由靜態內部類調用
    this.id = origin.id;  
    this.name = origin.name; 
    this.age = origin.age;
}

public int getId(){
    return this.id;
}

public String getName(){
    return this.name;
}

public int getAge(){
    return this.age;
}

public static class Builder{  //靜態內部類,通過該類來創建一個外部類對象,使用鏈式調用
    private Student2 target;  //創建一個外部類對象
    
    /**
     * 構造一個內部類對象,通過該對象設置屬性值
     * 如果存在必填參數,可以以帶參構造函數的方式傳過來
     * @param id  必填參數
     * @param name 必填參數
     */
    public Builder(int id , String name){ 
        target= new Student2();
        target.id = id;
        target.name = name;
    }
    
    /**
     * 調動builder對象的id方法設置id值
     * 返回builder對象,用來下一個方法設置屬性值
     * 這就是鏈式調用
     * @param id
     * @return
     */
    
    
    public Builder age(int age){
        target.age = age;
        return this;
    }
    
    
    /**
     *
     * @return
     */
    public Student2 build(){
        Student2 st = new Student2(target); //調用外部類的帶參構造函數初始化外部類的參數
        
        if(st.id < 100)   //builder模式是線性不安全的,所以我們必須要類創建完畢後才能對異常處理           
        try{
            throw new IllegalStateException("Age out of range"); // 非線程安全
        }
        catch( IllegalStateException e){
            st.id = 1000;
            e.printStackTrace();
        }
        return st; //返回一個外部類
    }
}


public static void main(String [] args){
    Student2 st = new Student2.Builder(1, "hubin").id(23).build();
    System.out.println(st.getId());
}
}

註:
1. builder模式中的構造函數都是私有的,不允許外部調用
2. builder模式中只有getter方法,沒有setter方法
3. builder模式中使用了鏈式調用,更具有可讀性
4. 對於一個對象如果需要傳入必填參數,則可以在構造函數中傳入參數,且類對應的參數應當有fianl修飾,如果沒有,如下代碼中id,name作為參數傳入毫無意義,因為仍然可以被修改。

public Builder(int id , String name){ 
    target= new Student2();
    target.id = id;
    target.name = name;
}

public Builder id(int id){   
    target.id = id;
    return this;
}

public Builder name(String name){
    target.name = name;
    return this;
}

Builder設計模式