DEV Community

Discussion on: The Builder Pattern in Java, and Dart Cascades

Collapse
 
marcguilera profile image
Marc Guilera • Edited

Good example. I like the idea but you point out 2 advantages of the builder pattern: First, it is easier to instantiate (or build) objects and second, is object immutability. With the dart cascade option, you lost the object immutability you had in the Java version.

I guess if we want that we have two option: make a builder in Dart or have a mutable class (with setters) subclass the immutable class (with getters) and use the mutable class with the cascade idea but once constructed pass around the superclass. I personally prefer the builder option in this case.

Collapse
 
jvarness profile image
Jake Varness

Excellent points Marc. I think with Dart it would be pretty easy to make a builder that creates an immutable object, and cascades can be easily used with a builder!

Collapse
 
marcguilera profile image
Marc Guilera • Edited

Absolutely! I usually create a builder that returns itself on each method to follow the usual builder pattern and make it easier for devs coming from other languages but the consumer can always choose to use cascading instead.

I really value immutability in my code so it's obvious from the API that after instantiation an object is not meant to be changed. Take a DI container for example, after setting it up with an InjectorBuilder (with registerFactory, registorSingleton, etc) I get an Injector that I pass around and only allows gets.

To your point of not having to copy the object to instantiate it from the builder and continuing with the Injector example, I have an Injector interface (or abstract class in Dart) and an InjectorImpl (which implements Injector + the setter methods). Then from the builder, I create a private instance of InjectorImpl which I modify through the builder and then on build return it as an Injector (basically a getter). This is an option if instantiating that object is not that expansive. I do not expose InjectorImpl to the outside world.

Collapse
 
aikar profile image
Daniel Ennis

Even better solution: Allow cascade operators on final parameters during object instantiation as shown in the example and map that to the initialized and final value.