这种初始化方法是推荐的吗?

时间:2017-06-07 04:15:44

标签: java

因此,当我编写自己的项目时,初始化对象出现了问题。我的班级有很多需要启动的属性,但并不总是所有属性都是。当我提出这个想法时(但我不确定它是否在任何地方使用过之前):

public class MyClass {
    public static final int DEFAULT1 = 1;
    public static final int DEFAULT2 = 2;
    public static final int DEFAULT3 = 3;
    private int attr1;
    private int attr2;
    private int attr3;
    private MyClass(){
        attr1 = DEFAULT1;
        attr2 = DEFAULT2;
        attr3 = DEFAULT3;
    }
    public static MyClass create(){
        return new MyClass();
    }
    public MyClass setAttr1(int attr1){
        this.attr1 = attr1;
        return this;
    }
    public MyClass setAttr2(int attr2){
        this.attr2 = attr2;
        return this;
    }
    public MyClass setAttr3(int attr3){
        this.attr3 = attr3;
        return this;
    }
}

当我创建一个新的MyClass实例时,我会这样做:

MyClass obj = MyClass.create().setAttr1(3).setAttr3(1);

它对我有用(因为我测试了它,但我还没决定在我的项目中使用它)。我的问题是,这是合法的吗?它会创建任何类型的内存/执行问题吗?

2 个答案:

答案 0 :(得分:7)

您的用例是Builder设计模式的完美示例。详细了解hereoracle doc about builder。另请阅读为什么Builder模式优于Java图例Joshua的其他创建模式,这在他的书中讨论,java的最佳实践  here

使用Builder设计模式转换后的课程如下所示。请注意,我假设attr1是可选的,attr2attr3是强制性的。

class MyClass {
    public static final int DEFAULT1 = 1;
    public static final int DEFAULT2 = 2;
    public static final int DEFAULT3 = 3;

    // assume attr1 is optional
    private int attr1;
    // assume attr2,3 is mandatory
    private int attr2;
    private int attr3;


    public MyClass(MyClassBuilder myClassBuilder) {
        this.attr1 = myClassBuilder.attr1;
        this.attr2 = myClassBuilder.attr2;
        this.attr3 = myClassBuilder.attr3;
    }

    //Builder Class
    public static class MyClassBuilder {

        // required parameters
        private int attr2;
        private int attr3;
        // optional parameters
        private int attr1;

        public MyClassBuilder(int attr2, int attr3){
            this.attr2 = attr2;
            this.attr3 = attr3;
        }

        public MyClassBuilder setAttr1(int attr1) {
            this.attr1 = attr1;
            return this;
        }


        public MyClass build(){
            return new MyClass(this);
        }

    }

}

现在使用下面的代码后,你可以创建对象(有/没有)可选参数。

public class MyClassTest {

    public static void main(String[] args) {
        MyClass myClass = new MyClass.MyClassBuilder(10,20).build();
    // without optional param
    System.out.println("without optional param");
    System.out.println("attr1 "+ myClass.getAttr1());
    System.out.println("attr2 "+ myClass.getAttr2());
    System.out.println("attr3 "+ myClass.getAttr3());

    // with optional param
    System.out.println("with optional param");
    MyClass myClassWithAllParam = new MyClass.MyClassBuilder(10,20).setAttr1(5).build();
    System.out.println("attr1 "+ myClassWithAllParam.getAttr1());
    System.out.println("attr2 "+ myClassWithAllParam.getAttr2());
    System.out.println("attr3 "+ myClassWithAllParam.getAttr3());

    }
}

输出如下: -

without optional param
attr1 0
attr2 10
attr3 20
with optional param
attr1 5
attr2 10
attr3 20

答案 1 :(得分:2)

另一个名字是Fluent Interface

您只需使用with代替set作为方法名称。 set命名是为JavaBeans约定保留的。