2
\$\begingroup\$

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.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

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?

\$\endgroup\$
3
  • \$\begingroup\$ Thank you so much for your time and help. It's very appreciated. Unfortunately I am incredibly tired right now, just wanted to quickly say thank you and that I'll be responding fully to your answer as soon as I get some sleep. I can say off the bat, you have a much better grasp of this than I do, and I'm not at all married to this method or pattern. Although I do have my own naive reasoning for most of it; but I'll go in detail about that later on. Thanks again, even if that answer is as far as you want to go, it's helpful all the same. \$\endgroup\$ Commented Dec 13, 2016 at 2:53
  • \$\begingroup\$ Sorry for the delay. Hopefully you are still interested in helping me out. The actual code I posted is just the template for the pattern. The Builder will hold all the logic for the class, The methods are empty for the example I posted. My library builds in OnCreate of an activity and it's resulting built class is saved throughout that activities lifecycles. Using the static setters kept the user from saving that built class as a field. I thought it made sense from other libraries I've seen. RxBindings etc... And I sort of used AlertDialog as a framework. \$\endgroup\$ Commented Dec 16, 2016 at 23:09
  • \$\begingroup\$ As far as testability, I can absolutely say no. I've not thought of it at all. It's always been on my list, I'm learning as I go, so some things simply have to wait for me to catch up. \$\endgroup\$ Commented Dec 16, 2016 at 23:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.