Dat Huynh
Dat Huynh

Reputation: 88

Is this method of initialization recommended?

So when I was coding my own project, a problem came up with initializing an object. My class has so many attributes that needs to be initiated BUT not always all of them, which . That's when I came up with this idea (but I'm not sure if it's used before anywhere):

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;
    }
}

When I create a new MyClass instance I would do:

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

It worked for me (kind of because I tested it but I haven't decided to use it in my project). My question is, is this legit? Would it create any kinds of memory/execution problems?

Upvotes: 2

Views: 111

Answers (2)

Amit
Amit

Reputation: 32376

Your use case is a perfect example of Builder design pattern. Read more about here and oracle doc about builder. Also read why Builder pattern has an advantage over other creation pattern by Java legend Joshua which is discuss in his book, best practice of java here.

Your converted class using Builder design pattern will look like below. Note that i assumed attr1 optional and attr2 and attr3 as mandatory.

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);
        }

    }

}

Now After that using below code, you can create the objects (with/without) optional param.

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());

    }
}

Output of which is below :-

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

Upvotes: 3

tsolakp
tsolakp

Reputation: 5948

Another name for it is Fluent Interface.

You just need to use with instead of set for method names. The set naming is kind of reserved for JavaBeans convention.

Upvotes: 2

Related Questions