構建器代替構造器

前言

靜態工廠方法和構造器有一個共同的侷限性:當有大量可選參數時,方法的數量會不受控制

當有大量可選參數時,開發者一般採用方法重載的方式來編寫構造器,面對大量的構造器調用者往往不知所云,尤其是參數類型相同的情況下,調用者往往要跟到源碼裏面去看才知道各個參數的意義。

面對這種情況,除了提供靜態工廠方法和構造器外,開發者往往還會將類設計成JavaBeans模式。
提供一個無參的構造方法,創建一個空對象,然後依次調用Set方法來設置屬性。
這麼做有以下缺點:

  • 構造過程被分解,對象可能不一致
  • 無法將類設計爲構造後不可變

類實例構造後仍然可變,意味着在多線程下可能出現數據安全問題,這需要調用者付出額外的精力去維護線程安全。

構建器

除了前面說的三種方法外,還有一種方法也應該被開發者考慮進來:構建器(Builder)。

使用構建器即可以保證安全性,也可以做到JavaBeans模式的可讀性,使得調用者代碼很好編寫,可選參數更好配置,得到一個流式的API。

例子

public class Car {
	//類型
	public final String type;
	//顏色
	public final String color;
	//全景天窗 可選
	public final Boolean panoramicSunroof;
	//座位數 可選
	public final Integer seat;

	private Car(Builder builder){
		this.type = builder.type;
		this.color = builder.color;
		this.panoramicSunroof = builder.panoramicSunroof;
		this.seat = builder.seat;
	}

	public static class Builder{
		private String type;
		private String color;
		private Boolean panoramicSunroof = false;//默認false
		private Integer seat = 4;//默認4座

		//必填屬性
		public Builder(String type,String color){
			this.type = type;
			this.color = color;
		}

		//可選屬性
		public Builder panoramicSunroof(Boolean panoramicSunroof){
			this.panoramicSunroof = panoramicSunroof;
			return this;
		}
		//可選屬性
		public Builder seat(Integer seat){
			this.seat = seat;
			return this;
		}

		public Car build() {
			return new Car(this);
		}
	}
	@Override
	public String toString() {
		String s =  "Car{" +
				"type='" + type + '\'' +
				", color='" + color + '\'' +
				", panoramicSunroof=" + panoramicSunroof +
				", seat=" + seat +
				'}';
		System.out.println(s);
		return s;
	}
}

客戶端構建實例

public class Client {
	public static void main(String[] args) {
		Car build = new Car.Builder("拖拉機", "騷紅").panoramicSunroof(true).seat(2).build();
		build.toString();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章