Effective Java 第2条 遇到多个构造器参数时要考虑使用构建器

遇到多个构造器参数时要考虑使用构建器

静态工厂方法和构造器都有一个共同的局限性,都不能很好的扩展到大量的可选参数。对于有多个参数的类来讲,如果类的初始化参数不是固定的,我们往往采取两种方式。
一是采用重叠构造器,例如:

public class Demo{
    
    
    private String var1;
    private String var2;
    private String var3;
    public Demo(String var1){
    
    
        this(var1,"");  
    }
    public Demo(String var1,String var2){
    
    
        this(var1,var2,"");
    }
    public Demo(String var1,String var2,String var3){
    
    
        this.var1 = var1;
        this.var2 = var2;
        this.var3 = var3;
    }
}

重叠构造器方法存在一些缺点:构造器没有特有名称 ,如果参数多了,不宜阅读,也很容易记不住参数顺序。

二是JavaBeans模式,即先用无参构造器创建出对象,再调用对象参数的各个setter方法。例如:

public class Main{
    
    
    public static void main(String[] args){
    
    
        Demo demo = new Demo("setVar1");
        demo = new Demo("setVar1","setVar2");
        demo = new Demo("setVar1","setVar2","setVar3");
    }
}

这种方式弥补了重叠构造器的不足,但是存在严重问题,如果构造过程被分成几个调用中,无法保证线程安全带来的类的不可变性影响,需要复出额外努力去保证类的一致性状态。

好在有第三种方式,既能保存重叠构造器模式的安全性,又能保证可读性,这就是建造者模式的一种体现,这种方式不直接生成对象,而是利用必要的参数调用构造器或者静态工厂方法,得到一个Builder对象,然后在Builder对象中调用类似于setter的方法,来设置可选参数,最后,调用无参的build方法来生成目标对象。build通常是他构建类的成员静态类。举个栗子:

public class Demo{
    
    
    private String name;
    private int age;
    private Date time;
    private String other;
    public static class Builder{
    
    
        private String name;
        private int age;
        private Date time;
        private String other;
        public Builder(String name,int age){
    
     // 静态成员类
            this.name = name;
            this.age = age;
        }
        public Builder time(Date time){
    
    
            this.time = time;
            return this;
        }
        public Builder other(String other){
    
    
            this.other = other; 
            return this; 
        }
         public Demo build(){
    
    
              return new Demo(this);
        }
    }
    private Demo(Builder builder){
    
    
        this.name = builder.name;
        this.age = builder.age;
        this.time = builder.time;
        this.other = builder.other;
    }
}

main:

public class Main{
    
    
    public static void main(String[] args){
    
    
        Demo demo = new Demo.Builder("xiaowu",1).time(new Date()).other("love java").build();
    }
}

与构造器相比,builder的优势在于,可以有多个可变参数,因为bulidre利用单独的方法来设置每一个参数,此外,构建器可以将多次调用某一个方法的参数集中到一个集合中。
uilder的模式也有不足之处,为了创建对象,需要先创建构建器,虽然创建builder的开销在实践中不是很明显,但是在某些十分注重性能的情况下,可能就会有问题,而且builder比重叠构造器模式更加沉长,所以建议只有当参数超过4个及以上,或者将来可能需要更多的参数,就可以考虑使用builder模式。

简而言之,如果类的构造器或者静态工厂中有多个参数,设计这种类时,builder模式是一种不错的选择,与构造器相比,使代码更加易于阅读和编写,同时也比JavaBean模式更加安全。


参考文章:https://www.jianshu.com/p/ec151f3feb57

猜你喜欢

转载自blog.csdn.net/qq_38941937/article/details/115055063