java靈活傳參之builder模式

flyingkid發表於2018-12-01

問題引入

例如Person類有以下屬性:

/**
 * @author 愛飄de小子
 * @date 2018年11月24日 下午2:28:23
 * @version 1.0
 */
@Data
public class Person {
	//必要屬性
	private String id;
	private String name;
 
	//非必要屬性
	private String address;
	private String gender;
	private Integer age;
 
        public Person() {
	}
 
	public Person(String id, String name, String address, String gender, Integer age) {
		this.id = id;
		this.name = name;
		this.address = address;
		this.gender = gender;
		this.age = age;
	}
  
}
複製程式碼

注: get和set方法採用lombok外掛的註解@Data生成(其中無參構造器可以用@NoArgsConstructor註解,有參構造器可以通過@AllArgsConstructor註解生成)

當客戶端要建立一個Person例項時,傳統的方式會這樣建立:

        //方式一
        Person person = new Person();
        person.setId("1");
        person.setName("愛飄de小子");
 
        person.setAge(24);
        person.setGender("男");
 
        //方式二
        Person person2 = new Person("1", "愛飄de小子", null, "男", 24);
複製程式碼

方式一 通過javabeans模式,提供的get和set方法建立例項,建立例項很容易,不足的是程式碼不夠簡潔。

方式二 通過構造器建立例項,如果物件的屬性較少,這種方式的最優的,如果屬性過多,這種方式並對客戶端來講並不友好。

如果使用構造器過載,引數多的情況下,需要過載的構造器個數將會以指數形式增長。

##builder模式 builder模式也叫作重疊構造器模式,改造Person物件如下:

import lombok.Data;
 
/**
 * @author 愛飄de小子
 * @date 2018年11月24日 下午2:28:23
 * @version 1.0
 */
@Data
public class Person {
	//必要屬性
	private String id;
	private String name;
 
	//非必要屬性
	private String address;
	private String gender;
	private Integer age;
 
	private Person(Builder builder) {
		this.id = builder.id;
		this.name = builder.name;
		this.address = builder.address;
		this.gender = builder.gender;
		this.age = builder.age;
	}
 
	@Data
	public static class Builder {
		private String id;
 
		private String name;
 
		private String address;
 
		private String gender;
 
		private Integer age;
 
		//必要屬性
		public Builder(String id,String name) {
			this.id = id;
			this.name = name;
		}
 
		public Builder setAddress(String address) {
			this.address = address;
			return this;
		}
		public Builder setGender(String gender) {
			this.gender = gender;
			return this;
		}
		public Builder setAge(Integer age) {
			this.age = age;
			return this;
		}
	}
 
}
複製程式碼

注:內部類Builder的setXXX方法每次都返回builder本身,這樣保證了Builder模式傳參的靈活性。

客戶端使用:

       Person person = new Person.
                Builder("1","愛飄de小子")
                .setAddress("成都")
                .setAge(24)
                .setGender("男")
                .build();
 
        Person person1 = new Person
                .Builder("2","輪迴")
                .setAge(21)
                .build();
複製程式碼

使用Builder模式相對於構造器的好處是傳參靈活,客戶端程式碼簡潔,客戶端的使用非常方便與易讀。

缺點: 1.每次建立Person物件都會建立Builder物件。 2.服務端程式碼陳餘。

相關文章