构建器

今天看了 《Effective Java》第二条: 遇到多个构造器参数时要考虑用构建器。做下学习笔记。

有时候一个类的域有很多,但并不是在创建时就需要的,可能必须的只有几个,那么我们会考虑构造器重载,例如一个商户有商户名,商户编码,所属代理商,法人姓名,身份证,地址等等,其中商户名和商户编码是必须的,那么只要提供一个这2个参数的构造器并且重载一些构造器即可,代码如下。

public class Merchant {
	
	private String merchantName;
	private String merchantCode;
	private String agentCode;
	private String corporateName;
	private String identity;
	private String addr;
	
	public Merchant(String merchantName, String merchantCode) {
		this.merchantName = merchantName;
		this.merchantCode = merchantCode;
	}

	public Merchant(String merchantName, String merchantCode, String agentCode) {
		super();
		this.merchantName = merchantName;
		this.merchantCode = merchantCode;
		this.agentCode = agentCode;
	}

	public Merchant(String merchantName, String merchantCode, String agentCode, String corporateName) {
		super();
		this.merchantName = merchantName;
		this.merchantCode = merchantCode;
		this.agentCode = agentCode;
		this.corporateName = corporateName;
	}

	public Merchant(String merchantName, String merchantCode, String agentCode, String corporateName, String identity) {
		super();
		this.merchantName = merchantName;
		this.merchantCode = merchantCode;
		this.agentCode = agentCode;
		this.corporateName = corporateName;
		this.identity = identity;
	}

	public Merchant(String merchantName, String merchantCode, String agentCode, String corporateName, String identity,
			String addr) {
		super();
		this.merchantName = merchantName;
		this.merchantCode = merchantCode;
		this.agentCode = agentCode;
		this.corporateName = corporateName;
		this.identity = identity;
		this.addr = addr;
	}
	
}

很明显,这里才6个域,如果有很多呢,很不方便,于是我们可以采用javabean的方式,现在也大多使用框架开发,也都是JavaBean的方式,那么不管多少个域,只要提供set、get方法,然后再提供一个无参构造器就行了,如下:

public class Merchant {

	private String merchantName;
	private String merchantCode;
	private String agentCode;
	private String corporateName;
	private String identity;
	private String addr;

	public String getMerchantName() {
		return merchantName;
	}

	public void setMerchantName(String merchantName) {
		this.merchantName = merchantName;
	}

	public String getMerchantCode() {
		return merchantCode;
	}

	public void setMerchantCode(String merchantCode) {
		this.merchantCode = merchantCode;
	}

	public String getAgentCode() {
		return agentCode;
	}

	public void setAgentCode(String agentCode) {
		this.agentCode = agentCode;
	}

	public String getCorporateName() {
		return corporateName;
	}

	public void setCorporateName(String corporateName) {
		this.corporateName = corporateName;
	}

	public String getIdentity() {
		return identity;
	}

	public void setIdentity(String identity) {
		this.identity = identity;
	}

	public String getAddr() {
		return addr;
	}

	public void setAddr(String addr) {
		this.addr = addr;
	}

}

这是我们大多数时候使用的方式,书中指出了这种方式的缺点:因为构造过程被分到了几个调用中,在构造过程中JavaBean可能处于不一致的状态,类无法仅仅通过检验构造器参数的有效性来保证一致性。试图使用处于不一致状态的对象,将会导致失败,这种失败与包含错误的代码大相径庭,因此调试起来十分困难。另外,JavaBean模式阻止了把类做成不可变的可能,就需要程序员付出额外的努力来确保他的线程安全。

这部分我现在还不是很好的理解。

除了重载构造器和JavaBean模式外,还可以使用构建器的方式,如下:

public class Merchant {

	private String merchantName;
	private String merchantCode;
	private String agentCode;
	private String corporateName;
	private String identity;
	private String addr;

	public static class Builder {
		private String merchantName;
		private String merchantCode;
		private String agentCode;
		private String corporateName;
		private String identity;
		private String addr;
		
		public Builder(String mchName, String code) {
			this.merchantName = mchName;
			this.merchantCode = code;
		}
		
		public Builder agent(String agentCode) {
			this.agentCode = agentCode;
			return this;
		}
		
		public Builder corporate(String corporateName) {
			this.corporateName = corporateName;
			return this;
		}
		
		public Builder identity(String identity) {
			this.identity = identity;
			return this;
		}
		
		public Builder address(String addr) {
			this.addr = addr;
			return this;
		}
		
		public Merchant build() {
			return new Merchant(this);
		}
	}
	
	private Merchant(Builder builder) {
		this.addr = builder.addr;
		this.identity = builder.identity;
		this.corporateName = builder.corporateName;
		this.agentCode = builder.agentCode;
	}

}

使用构建器的话就很灵活了,采用链式调用,如:

Merchant mer = new Merchant.Builder("测试商户", "M0001").agent("A0223").address("北京西直门外大街").build();

构建器优点:

1.有多个可变参数,构造器只能有一个;

2.比JavaBean安全;

缺点:

1.创建对象必须先创建他的构建器;

2.代码比重载构造器更冗长。


现在对此的理解还不是很深入,但算是多一种思路吧,以后有新的想法再来补充。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值