大家好,我是烤鸭:
今天说一下初始化对象的几种方式:
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版》