In Part I, we created a separate Builder class in an attempt to move away from a constructor with too many parameters. In the process, the separate Builder ended up taking on the additional responsibility of supplying default values, blurring the line between a Builder and Factory.
Though a step in the right direction, it didn’t actually fix any of the
Address constructor’s original problems, unfortunately. Oops. Other classes can still call it directly, meaning all of the risks of having a method with multiple parameters of the same type are still there, and we have another class in our system to maintain.
What we need is a strictly controlled way of creating
Address objects that can be accessed by test code and prod code that is decoupled from the current constructor and it’s baggage.
3) Pulling the Builder inside Address
Let’s remodel the Builder as a static inner class within the
|Looking good||Needs improvement|
We have coupled the Builder to the
Also, we have finally gotten rid of the public all-args constructor with too many parameters!
To take it even further, we removed all public constructors. The Private Constructor pattern tells collaborators that object construction is internal and explicitly controlled by the class itself. The Builder is now the only way to construct an
However, the dual responsibilities of the separate Builder class have reared their ugly head. In order to prevent leaking test code (the default values) into our prod code (the inner Builder), we had to remove them altogether for now and go back to specifying them in the test class itself.
This means we go back to the problem of confusing arbitrary values appearing in our tests.
Next up, Part III - where we truly divide the responsibilities for object construction into a Builder and a Factory, removing the arbitrary default values from the test itself.