effective java读书札记值第2条:遇到多个构造器参数时要考虑用构造器

对于一个参数有多个的构造器的类,程序员一向习惯采用重叠的构造器模式。

public class Person {
	private String Id;
	private String name;
	private String address;
	
	
	public Person(String id) {
		Id = id;
	}

	public Person(String name, String address) {
		super();
		this.name = name;
		this.address = address;
	}
	
	public Person(String id, String name, String address) {
		Id = id;
		this.name = name;
		this.address = address;
	}
	
	

}

重叠构造器模式可行,但是当有许多参数的时候,客户端代码会很难编写。并且难以阅读。遇到许多构造器参数的时候,还有第二种代替办法,即JavaBean模式(现在这种模式可以说是非常流行了)。在这种模式下,调用一个无参构造器来创建对象,然后调用setter方法来设置每个必要的参数。以及每个相关的可选参数:

public class Person {
	private String Id;
	private String name;
	private String address;
	
	public Person() {
		super();
	}
	
	public String getId() {
		return Id;
	}
	public void setId(String id) {
		Id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	
	
	

}

这样的话,我们每次用那个无参的构造器,然后想设置哪个变量就设置哪个。但是JavaBeans模式自身有着很严重的缺点。因为构造过程被分到了几个调用中。在构造过程中JavaBean可能处于不一致的状态。类无法仅仅通过检验构造器参数的有效性来保证一致性。


幸运的是,还有第三种替代方法,既能保证像重叠构造器模式那样的安全性,也能保证像JavaBeans模式那么好的可读性。这就是Builder模式。不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器,得到一个builder对象。然后客户端在builder对象上嗲用类似于setter的方法,来设置每个相关的可选参数。最后,客户端调用无参的builder方法来生成不可变的对象。这个builder是它构建器的类的静态成员类。

public class Person {
	private String Id;
	private String name;
	private String address;
	
	public static class Builder{
		//所必须的参数
		private final String Id;
		
		//可选的参数
		private String name = "";
		private String address = "" ;
		
		public Builder(String id){
			this.Id = id;
		}
		
		public Builder name(String name){
			this.name = name;
			return this;
		}
		
		public Builder address(String address){
			this.address = address;
			return this;
		}
		
		public Person build(){
			return new Person(this);
		}
	}
	
	private Person (Builder builder){
		this.Id = builder.Id;
		this.name = builder.name;
		this.address = builder.address;
	}

}

调用:

Person person = new Person.Builder("100").address("ss").name("ss").build();

简而言之,如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder模式就是种不错的选择,特别是当大多数参数都是可选的时候,与使用传统的重叠构造器模式相比,使用Builder模式的客户端代码将更易于阅读和编写,构造器也比JavaBeans更加安全。


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。