DEV Community

Discussion on: When Builder is anti-pattern

Collapse
 
siy profile image
Sergiy Yevtushenko

There is a pattern which allows to solve all these issues. Usually it is involved for creating DSL's to limit possible choices and avoid user mistakes. The idea of the pattern is quite simple: when builder is created, it returns interface which has limited number of methods to call and does not have final build() method. Methods of first interface return other interfaces with other set of methods and so on an so forth, until last interface is reached, which has build() method.

This pattern allows to avoid Builder pattern issues (and even allows to enforce code style, for example make all invocations to use same order of setting field values), but it's implementation is somewhat verbose. For DSL's this is perfectly OK, but for building POJO's it might be overkill.

I'm going to describe this pattern in one of the next posts.

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

So it's more like a Buildup pattern? 😊

Thread Thread
 
siy profile image
Sergiy Yevtushenko

Basically yes. Thanks for naming suggestion :)

Collapse
 
jmkelm08 profile image
jmkelm08

I believe what you are describing is commonly referred to as a fluent interface.

Thread Thread
 
siy profile image
Sergiy Yevtushenko

Fluent interface is orthogonal to the pattern described above.

Thread Thread
 
jmkelm08 profile image
jmkelm08

I don't see how? A fluent interface attempts to guide you through a process without you really having to read the documentation (you feel like you are already fluent in the API). For example, I could have a class like ClientFactory with a single method createClient(). The return from that method could be an object with two methods forAmazon() or forGoogle(). Depending on which method you call you may have different options for how to have the client authenticate. The fluent API gives you limited valid options until you hit a terminal method that finally builds and returns the object you are looking for. It sounds exactly like what you were describing in your DSL like solution above.

Thread Thread
 
siy profile image
Sergiy Yevtushenko

Out of curiosity I've checked what Wikipedia says about fluent interface:

Note that a "fluent interface" means more than just method cascading via chaining; it entails designing an interface that reads like a DSL, using other techniques like "nested functions and object scoping".

So, seems I was wrong about orthogonality. From the other hand, looks like fluent interface is designed to be "DSL-like", so basically it's just two different names for same thing.