Completely static builder implementation

Posted on

Problem

CustomClass.class

Description

The CustomClass is created with init(), which returns a CustomBuilder saving both as static fields.

public class CustomClass {

    private static CustomClass customClass;
    private static CustomBuilder customBuilder;

    public static CustomBuilder init(){
        customClass = new CustomClass();
        return customBuilder = new CustomBuilder();
    }

    public static CustomClass customClass() {
        return customClass;
    }

    public static void setMethodA() {
        customBuilder.methodA();
    }

    public static void setMethodB() {
        customBuilder.methodB();
    }


    public static class CustomBuilder {

        public CustomBuilder methodA() {
            return this;
        }

        public CustomBuilder methodB() {
            return this;
        }

        public CustomClass build() {
            return customClass();
        }
    }
}

UsageActivity.class

Description

The UsageActivity calls init(),methodA() then build() within its onCreate(savedInstanceState). When something() is called it runs CustomClass.setMethodB().

    public class UsageActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        CustomClass.init().methodA().build();
    }

    protected void something(){
        CustomClass.setMethodB();
    }
}

Reasoning

Once the custom class’ initial method is called in the activities onCreate, all its methods are static and accessible to the activity and its fragments.

As long as I handle data saving and lifecycles, it makes the library more flexible and creates less local variable management.

I’m not sure if this is the best way to go about it however. It all works as far as I can tell.

Does anyone see any issues or glaring mistakes?

Thank you.

Solution

I’m afraid and sorry to say that your code does not make a lot of sense.

A Builder is supposed to build an object. As such it replaces the constructor. That builders allow for chained method calls using return this is some syntactic sugar that’s frequently used for builders. However, return this doesn’t turn an arbitrary class into a Builder.

A Builder is used when it adds value over a regular constructor call. There are various reasons why one would introduce a Builder, to name a few:

  • The constructor call would be too complex or confusing.
  • A set of similar objects shall be created which differ in only a few elements.
  • To allow multiple method calls until the object is created while still retaining immutability for the final object.

The general expectation is that neither Builders nor classes created by them are Singletons, and that Builders and the constructed objects are independent of each other, that is, that they do not have side effects on each other.
In other words, one can create two Builders, and those two Builders would have nothing in common but being Builders for the same class. And then call build() on each of them, and end up with two different objects of possibly the same class but otherwise unrelated with each other.

The source of this is the massive over-use of static on non-final fields. Using static for fields without making them final is almost always a mistake.

More confusing things are

  • static Setters
  • Setters which have side effects on something else, something seemingly unrelated

Also, have you ever thought of the testability of the code in question?

Leave a Reply

Your email address will not be published. Required fields are marked *