Builder設計模式


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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM