1. 程式人生 > >JAVA構造物件的幾種方式(構建器、構造器)

JAVA構造物件的幾種方式(構建器、構造器)

大家好,我是烤鴨:

    今天說一下初始化物件的幾種方式:

        1.    多引數構造器

        2.    構建器

        3.    構造器後 + get/set方法

舉個例子:

    這裡有個機構entity,提供一個預設構造器

package com.xxx.xxx.modules.sys.entity;

/**
 * 機構Entity
 * @version 2013-05-15
 */
public class Office {

	private static final long serialVersionUID = 1L;
	private Area area;		// 歸屬區域
	private String code; 	// 機構編碼
	private String type; 	// 機構型別(1:公司;2:部門;3:小組)
	private String grade; 	// 機構等級(1:一級;2:二級;3:三級;4:四級)
	private String address; // 聯絡地址
	private String zipCode; // 郵政編碼
	private String master; 	// 負責人
	private String phone; 	// 電話
	private String fax; 	// 傳真
	private String email; 	// 郵箱
	private String useable;//是否可用
	private User primaryPerson;//主負責人
	private User deputyPerson;//副負責人
	private List<String> childDeptList;//快速新增子部門
	
	private String officeCode; //新增欄位,門店id,和code值一樣
	private String businessArea; //2.0新增欄位,營業面積
	private String businessHours; //2.0新增欄位,營業時間
	
	public Office(){
		super();
	}
}

如果想建立一個這樣的物件進行引數傳遞或者進行其他操作(資料庫等等)

1.   多引數構造器

 這是全參構造器:

public Office(Area area, String code, String type, String grade, String address, String zipCode, String master, String phone, String fax, String email, String useable, User primaryPerson, User deputyPerson, List<String> childDeptList, String officeCode, String businessArea, String businessHours, String jxName) {
		this.area = area;
		this.code = code;
		this.type = type;
		this.grade = grade;
		this.address = address;
		this.zipCode = zipCode;
		this.master = master;
		this.phone = phone;
		this.fax = fax;
		this.email = email;
		this.useable = useable;
		this.primaryPerson = primaryPerson;
		this.deputyPerson = deputyPerson;
		this.childDeptList = childDeptList;
		this.officeCode = officeCode;
		this.businessArea = businessArea;
		this.businessHours = businessHours;
		this.jxName = jxName;
	}

2.  構建

     這是全參構建器:

private Office(Office.Builder builder){
		this.id = builder.id;
		this.area = builder.area;
		this.code = builder.code;
		this.type = builder.type;
		this.grade = builder.grade;
		this.address = builder.address;
		this.name = builder.name;
		this.email = builder.email;
		this.phone = builder.phone;
		this.zipCode = builder.zipCode;
		this.master = builder.master;
		this.parent = builder.parent;
		this.parentIds = builder.parentIds;
		this.fax = builder.fax;
		this.sort = builder.sort;
		this.primaryPerson = builder.primaryPerson;
		this.deputyPerson = builder.deputyPerson;
		this.childDeptList = builder.childDeptList;
		this.officeCode = builder.officeCode;
		this.businessArea = builder.businessArea;
		this.useable = builder.useable;
		this.businessHours = builder.businessHours;
		this.delFlag = builder.delFlag;
		this.createBy = builder.createBy;
		this.updateBy = builder.updateBy;
		this.updateDate = builder.updateDate;
		this.createDate = builder.createDate;
	}

	//利用構建器建立物件
	public static class Builder extends Office{
		private static final long serialVersionUID = 1L;
		private Area area;		// 歸屬區域
		private String code; 	// 機構編碼
		private String type; 	// 機構型別(1:公司;2:部門;3:小組)
		private String grade; 	// 機構等級(1:一級;2:二級;3:三級;4:四級)
		private String address; // 聯絡地址
		private String zipCode; // 郵政編碼
		private String master; 	// 負責人
		private String phone; 	// 電話
		private String fax; 	// 傳真
		private String email; 	// 郵箱
		private String useable;//是否可用
		private User primaryPerson;//主負責人
		private User deputyPerson;//副負責人
		private List<String> childDeptList;//快速新增子部門

		private String officeCode; //新增欄位,門店id,和code值一樣
		private String businessArea; //2.0新增欄位,營業面積
		private String businessHours; //2.0新增欄位,營業時間
		public Builder() {
			super();
		}

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

		public Office build(){
			return new Office(this);
		}

		public Builder area(Area area){
			this.area = area;
			return this;
		}

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

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

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

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

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

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

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

		public Builder password(String master) {
			this.master = master;
			return this;
		}

		public Builder parent(Office parent) {
			this.parent = parent;
			return this;
		}

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

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

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

		public Builder email(String email) {
			this.email = email;
			return this;
		}
		public Builder useable(String useable) {
			this.useable = useable;
			return this;
		}

		public Builder sort(Integer sort) {
			this.sort = sort;
			return this;
		}

		public Builder primaryPerson(User primaryPerson) {
			this.primaryPerson = primaryPerson;
			return this;
		}

		public Builder deputyPerson(User deputyPerson) {
			this.deputyPerson = deputyPerson;
			return this;
		}

		public Builder childDeptList(List<String> childDeptList) {
			this.childDeptList = childDeptList;
			return this;
		}

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

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

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

		public Builder delFlag(String delFlag) {
			this.delFlag = delFlag;
			if(StringUtils.isBlank(delFlag)){
				this.delFlag = IDBConstant.APPLICATION_DELETE_FLAG_VALID + "";
			}
			return this;
		}

		public Builder createBy(User createBy) {
			this.createBy = createBy;
			return this;
		}

		public Builder updateBy(User updateBy) {
			this.updateBy = updateBy;
			return this;
		}

		public Builder createDate(Date createDate) {
			this.createDate = createDate;
			return this;
		}

		public Builder updateDate(Date updateDate) {
			this.updateDate = updateDate;
			return this;
		}

	}

3.  get/set方法

自動生成就行
        public List<String> getChildDeptList() {
		return childDeptList;
	}

	public void setChildDeptList(List<String> childDeptList) {
		this.childDeptList = childDeptList;
	}

	public String getUseable() {
		return useable;
	}

	public void setUseable(String useable) {
		this.useable = useable;
	}

	public User getPrimaryPerson() {
		return primaryPerson;
	}

	public void setPrimaryPerson(User primaryPerson) {
		this.primaryPerson = primaryPerson;
	}

	public User getDeputyPerson() {
		return deputyPerson;
	}

	public void setDeputyPerson(User deputyPerson) {
		this.deputyPerson = deputyPerson;
	}

	public Office getParent() {
		return parent;
	}

	public void setParent(Office parent) {
		this.parent = parent;
	}

	@NotNull
	public Area getArea() {
		return area;
	}

	public void setArea(Area area) {
		this.area = area;
	}
	
	@Length(min=1, max=1)
	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	@Length(min=1, max=1)
	public String getGrade() {
		return grade;
	}

	public void setGrade(String grade) {
		this.grade = grade;
	}

	@Length(min=0, max=255)
	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	@Length(min=0, max=100)
	public String getZipCode() {
		return zipCode;
	}

	public void setZipCode(String zipCode) {
		this.zipCode = zipCode;
	}

	@Length(min=0, max=100)
	public String getMaster() {
		return master;
	}

	public void setMaster(String master) {
		this.master = master;
	}

	@Length(min=0, max=200)
	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	@Length(min=0, max=200)
	public String getFax() {
		return fax;
	}

	public void setFax(String fax) {
		this.fax = fax;
	}

	@Length(min=0, max=200)
	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	@Length(min=0, max=100)
	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	@Override
	public String toString() {
		return name;
	}

	public String getOfficeCode() {
		return officeCode;
	}

	public void setOfficeCode(String officeCode) {
		this.officeCode = officeCode;
	}

	public String getBusinessArea() {
		return businessArea;
	}

	public void setBusinessArea(String businessArea) {
		this.businessArea = businessArea;
	}

	public String getBusinessHours() {
		return businessHours;
	}

	public void setBusinessHours(String businessHours) {
		this.businessHours = businessHours;
	}
}


	public List<String> getChildDeptList() {
		return childDeptList;
	}

	public void setChildDeptList(List<String> childDeptList) {
		this.childDeptList = childDeptList;
	}

	public String getUseable() {
		return useable;
	}

	public void setUseable(String useable) {
		this.useable = useable;
	}

	public User getPrimaryPerson() {
		return primaryPerson;
	}

	public void setPrimaryPerson(User primaryPerson) {
		this.primaryPerson = primaryPerson;
	}

	public User getDeputyPerson() {
		return deputyPerson;
	}

	public void setDeputyPerson(User deputyPerson) {
		this.deputyPerson = deputyPerson;
	}

	public Office getParent() {
		return parent;
	}

	public void setParent(Office parent) {
		this.parent = parent;
	}

	@NotNull
	public Area getArea() {
		return area;
	}

	public void setArea(Area area) {
		this.area = area;
	}
	
	@Length(min=1, max=1)
	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	@Length(min=1, max=1)
	public String getGrade() {
		return grade;
	}

	public void setGrade(String grade) {
		this.grade = grade;
	}

	@Length(min=0, max=255)
	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	@Length(min=0, max=100)
	public String getZipCode() {
		return zipCode;
	}

	public void setZipCode(String zipCode) {
		this.zipCode = zipCode;
	}

	@Length(min=0, max=100)
	public String getMaster() {
		return master;
	}

	public void setMaster(String master) {
		this.master = master;
	}

	@Length(min=0, max=200)
	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	@Length(min=0, max=200)
	public String getFax() {
		return fax;
	}

	public void setFax(String fax) {
		this.fax = fax;
	}

	@Length(min=0, max=200)
	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	@Length(min=0, max=100)
	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	@Override
	public String toString() {
		return name;
	}

	public String getOfficeCode() {
		return officeCode;
	}

	public void setOfficeCode(String officeCode) {
		this.officeCode = officeCode;
	}

	public String getBusinessArea() {
		return businessArea;
	}

	public void setBusinessArea(String businessArea) {
		this.businessArea = businessArea;
	}

	public String getBusinessHours() {
		return businessHours;
	}

	public void setBusinessHours(String businessHours) {
		this.businessHours = businessHours;
	}

4.    用法

        如果我想構造一個物件

    4.1    構造器

        直接上圖吧:

    

    當我new Office()的時候,我不知道需要傳入什麼型別的引數,也不知道每個引數代表哪個欄位。

多個欄位的時候,不推薦這種方式。幾個欄位算多?我覺得5+吧。

    4.2    構建器

    

        上圖的欄位比例子中的多了幾個, 構建器構造的物件很清晰,而且相對利於維護,構造器的話,需要修改構造方法,構建器在builder物件中加屬性就好了。為什麼說構建器更安全,因為一個物件在可能有多個構造器,通過構造器來建立,沒法保證一致性。比如:new Office(id)和new Office(name),這兩個物件怎麼保證一致呢。

    4.3    get/set方法

        不演示了,就拿上圖來說,set屬性需要多少行程式碼?起碼多兩倍不止。

5.  關於構建器和構造器

 JavaBean模式自身有嚴重的缺點,因為構造過程被分到幾個呼叫中,在構造過程中Javabean可能處於不一致的狀態,類無法僅僅通過檢驗構造器引數的有效性來保證一致性。JavaBean模式阻止了把類做成不可變的可能,這就需要程式設計師付出額外的努力確保執行緒安全 。

Java中傳統的抽象工廠實現是Class物件,newInstance方法總是企圖呼叫類的無參構造器,這個構造器甚至可能根本不存在。Class.newInstance破壞了編譯時的異常檢查。Builder模式也存在不足。為了建立物件,必須先建立它的構建器。在十分注重效能的情況下,可能就成問題了。Builder模式還比重疊構造器模式更加冗長,因此它只在有很多引數的時候才使用,比如4個或者更多個引數。通常最好一開始就使用構建器。

  如果類的構造器或者靜態工廠中具有多個引數,設計這種類時,Builder模式就是種不錯的選擇,特別是當大多數引數都是可選的時候。與使用傳統的重疊構造器模式相比,使用Builder模式的客戶端程式碼將更易於閱讀和編寫,構建器也比JavaBeans更加安全。

參考資料

《Effective Java 中文版 第2版》