创建和销毁对象:遇到多个构造器参数是考虑使用构建器
package effective.yk02;
/**
* @author Yoko
* 《Effective Java》第二版:
* 创建和销毁对象
* 第二条:遇到多个构造器参数是考虑使用构建器
* 静态工厂方法和构造器都有局限性,不能很好的扩展到大量的可选参数,对于一个类,在实际开发过程中,类中可能会存在很多属性,而且有些属性在实例化对象中是必须的,
* 所以一般开发人员会使用:①重叠构造器模式,在这种模式下,提供第一个只有必要参数的构造器,第二个构造器有一个可选参数,第三个构造器有两个可选参数,以此类推,最后
* 一个构造器包含所有的可选参数。在需要创建实例的时候,虽然利用参数列表最短的构造器,但是列表中包含了要设置的所有参数,所以当存在许多参数的时候,客户端代码会
* 很难写,并且难以阅读,如果客户端不小心颠倒了参数的顺序,编译器不会报错,但是在程序运行时会出现错误。
* ②使用JavaBeans模式,调用无参数的构造器创建对象,然后调用setter方法来设置必要参数和相关的可选参数。但是因为构造过程被分到几个调用中,在构建过程中JavaBean
* 可能处于不一致的状态,类无法仅仅通过检验构造器参数的有效性来保持一致性。试图使用处于不一致状态的对象,将会导致失败。
* ③Builder模式,不直接创建想要的对象,而是让客户端利用所有必要的参数调用构造器或者静态工厂方法,获取一个builder对象。然后客户端在builder对象上调用类似于
* setter方法来设置每个相关的可选参数,最后客户端调用无参的build方法来生成不可变的对象。这个builder是它构建的类的静态成员。代码如下:
*/
public class Animal {
private String name;//必须
private String varieties;//必须
private String color;//可选
private Integer age;//可选
private double weight;//可选
public static class Builder {
private final String name;
private final String varieties;
private String color = "block";
private Integer age = 1;
private double weight = 5.0;
public Builder(String name,String varieties){
this.name = name;
this.varieties = varieties;
}
public Builder color(String color){
this.color = color;
return this;
}
public Builder age(Integer age){
this.age = age;
return this;
}
public Builder weight(double weight){
this.weight = weight;
return this;
}
public Animal build(){
return new Animal(this);
}
}
private Animal(Builder builder){
this.name = builder.name;
this.varieties = builder.varieties;
this.color = builder.color;
this.age = builder.age;
this.weight = builder.weight;
}
@Override
public String toString() {
return "Animal [name=" + name + ", varieties=" + varieties + ", color="
+ color + ", age=" + age + ", weight=" + weight + "]";
}
public static void main(String[] args) {
Animal animal = new Animal.Builder("杰瑞", "哈士奇").color("灰色").age(2).weight(54.6).build();
System.out.println(animal.toString());
}
}