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版》