构造器模式的具体作用和setter的区别

发布时间 2023-10-25 12:11:35作者: Silentdoer

1.构造器模式其实没有什么神秘性,它最终实现的功能和通过先new对象,然后一行一行调用该对象的setter来设置(注意,不是初始化)该对象的属性,最终形成的对象没有区别;

2.那构造器的作用是什么呢?作用如下:

2.1和用setter初始化对象属性最大的区别在于 构造器是要求先给出 该类型所有要初始化字段的 值,通过链式调用设置,全部初始化字段值 给出后,再调用build方法初始化该对象并返回;

所以这里的区别有点像C#里的流,前面设置一堆流处理逻辑,只有最后一步是产生List对象;

即先给出类型所有要初始化字段的所有字段值,然后以这些值来初始化创建该对象(注意,不是先创建,然后set,而是初始化时给定这些初始值);

即没有build之前的字段设置是在对象创建之前的,而setter是值对象创建之后的;

2.2第二个就是可以链式调用初始化;

 

2.3构造器模式不会暴露类的setter方法,构造器的设置值的方法只在类对象初始化的时候用到,build创建好对象后builder的设置值的方法就没有用了;

所以可以实现类Foo的三个字段都是没有setter的,但是又希望能可选择的初始化(比如只初始化两个字段),如果没有构造器则必须实现很多个构造方法;

因此Foo的构造器一般是在Foo类里面,这样可以在Foo没有暴露setter方法的前提下给Foo字段设值:

class Foo {
    private Integer age;
    private String name;
    private String num;
    
    // 这三个字段只有getter,没有setter,getter代码就不写了知道有就行
    
    public static FooBuilder builder() {
        return new FooBuilder();
    }
    
    public class static FooBuilder {
        private Integer age;
        private String name;
        private String num;
        
        FooBuilder age(Integer age) {
            this.age = age;
            return this;
        }
        
        FooBuilder name(Strng name) {
            this.name = name;
            return this;
        }
        
        FooBuilder num(String num) {
            this.num = num;
            return this;
        }
        
        Foo build() {
            Foo foo = new Foo();
            // TODO 这里还可以判断this.age是否为空或者默认值,如果是空则不对foo.age设值(看具体Builder策略来实现)
            foo.age = this.age;
            foo.name = this.name;
            foo.num = this.num;
            return foo;
        }
    }
}

通过上面的构造器实现,则可以保留Foo不对外提供setter的权限控制,但是在初始化时又能链式的对所有Foo字段的可选择的初始化,且FooBuilder对象在build后再进行age(..)等设值不会影响已经build出的Foo对象(即Foo对象初始化后就不提供

对外setter;如果用构造方法实现就要很多个构造方法)

而且Builder还能通过多个Builder接口来实现,必须先填name,再填password,即builder()方法返回NameStep接口,而此接口的name(..)方法返回PasswordStep接口,而password(..)则返回BuildStep普通接口(build方法);

然后FooBuilder要实现这三个接口;

还能在build里对整体做合法性校验