52

I'm very new to design patterns and am having trouble with the difference between fluent interfaces and the Builder pattern.

I understand the concept of fluent interfaces. But the builder pattern is a little confusing. I cannot understand the use of a Director in the Builder pattern.

Can I use the Builder pattern and Fluent Interface together? If so, then how should I do so with a Director and a concrete builder?

My question is not about advantages of builder pattern. But the aim of this question is to know the relation between builder pattern and fluent interface.


Edit with UML sequence diagram for Builder from GoF:

Sequence diagram with director

Community
  • 1
  • 1
Sagar
  • 980
  • 1
  • 11
  • 27
  • 1
    *Can I use Builder pattern and fluent Interface together?* yes you can, there's a great example posted [here](http://stackoverflow.com/q/1673841/1065197) – Luiggi Mendoza Jul 30 '13 at 03:22
  • More examples are at http://stackoverflow.com/questions/328496/when-would-you-use-the-builder-pattern/ . – Andy Thomas Jul 30 '13 at 03:38
  • 6
    Can I know how this question is duplicate of the above mention question ? Since it is about relation between fluent interface and builder pattern. – Sagar Dec 03 '15 at 15:34
  • 7
    I'm not sure that this question was answered properly in the duplicate. Many people refer to GoF Builder incorrectly. True Builder from GoF allows extending (adding) `ConcreteBuilder` classes without modifying the `Client` class or `Director` class. See the sequence diagram I added to your question. Method chaining or fluent interface are not Builder by GoF. The examples in GoF don't use method chaining at all. – Fuhrmanator Jan 19 '16 at 15:28
  • 1
    I found the following useful in finding out the difference. Here the author calls builder pattern version 1 and version 2 for fluent Interface http://blog.crisp.se/2013/10/09/perlundholm/another-builder-pattern-for-java – Hari Rao Jan 18 '17 at 12:16
  • @Gordon's answer provides more idea about the fluent interface. – NeoZoom.lua Sep 11 '20 at 18:42

2 Answers2

146

Fluent Interfaces are semantic facades. You put them on top of existing code to reduce syntactical noise and to more clearly express what the code does in an ubiquitous language. It's a pattern used when building an internal Domain Specific Language. It's about readability.

A director/builder orchestrates the building of something. That is, if you are building a Pizza baking machine, the Director would make sure that the steps from order to pizza are executed in the right order with the right data by the right builder. It's about validation and delegation.

You can certainly put a Fluent Interface on top of a Director/Builder pattern to make it read more - well - fluently and to emphasize the domain concepts (vs. the technical process of building and delegating). That would probably be an Expression Builder then.

I'd like to stress that Fluent Interfaces are not just Method Chaining. It's a common misconception. Method Chaining is one approach to implement a Fluent Interface but it's not the same, because it lacks the semantic qualities, e.g. this is not a Fluent Interface:

SomeObject.setFoo(1).setBar(2).setBaz(3);

The above does not express anything about SomeObject. It's not a facade on top of some semantic model. It's just some methods chained. An example of a Fluent Interface would be a SQL query builder, e.g.

SQLBuilder.select('foo').from('bar').where('foo = ?', 42).prepare();

Under the hood of that API lies the code to create an SQL statement. It might include several objects and the calls shown could very well create a Select object, call a setter on it, create a Condition object and apply it to the Select object and finally return a Statement object. But all that is hidden from us. This also highlights another aspect of Fluent Interfaces: they might violate SOLID and Law of Demeter. But since it's a facade on top of code that hopefully follows these design principles, it doesn't matter that much, because you localize the violations to the Fluent Interface.

JohnnyLambada
  • 12,700
  • 11
  • 57
  • 61
Gordon
  • 312,688
  • 75
  • 539
  • 559
  • 1
    What would be the semantics if code did `var foo = SQLBuilder.select('foo').from('bar'); var bar=foo.where(expr1,42); foo.where(exp2,42).prepare(); bar.prepare()`? What do Fluent interfaces have to say about the mutability or immutability of intermediate results? My understanding is that there aren't really any rigid conventions, but perhaps I'm mistaken? – supercat Sep 23 '14 at 13:38
  • 1
    @supercat I'm not aware of any such conventions. You can split the various calls like you show in your example. – Gordon Sep 23 '14 at 16:56
  • Would the second call to `foo.where` be expected to modify the object which is identified by `bar`? – supercat Sep 23 '14 at 17:46
  • 2
    @supercat your SQLBuilder would return instances of *itself* from any call, so your foo and your bar both refer to the builder. It's only when you call prepare that you finish the building process and get a prepared statement object. – Gordon Sep 23 '14 at 18:11
  • 3
    I see no difference between your SQLBuilder and SomeObject. Each of them are simple method chaining. My opinion is that fluent interfaces are simply a pattern for method chaining. The coolest ones being when they are built to take advantages of an IDE, by returning an object that only supports the operations permitted from that point on. You also say method chaining is one approach, but I think that's false, a fluent interface without method chaining is not fluent at all. – Didier A. Aug 07 '15 at 01:44
  • @didibus get yourself a copy of http://martinfowler.com/books/dsl.html to verify my answer :) – Gordon Aug 07 '15 at 07:56
  • 2
    @Gordon Technically he coined the term, so I guess he is the reference. Yet I still think he over sells most of his stuff. Fluent is effectively method chaining refined. I'm talking of chaining in smalltalk speak, where you invoke a method on the return of another, so you can skip having a local variable. Now if you use this feature to build a clever DSL, you're being fluent. The thing is, "clever" is arguable. Both your examples are fluent, one is just cleverer, thus it feels more fluent. But what is the first one if not fluent? – Didier A. Aug 12 '15 at 19:58
  • @Gordon In Martin Fowler's terminology, he'd say the first one is method chaining, while the second one is fluent. That's fair. Yet I feel the first one is method cascading and the second one is a combination of more things which in both cases create a fluent interface. The fluency comes from the cleverness. The steps follow each other in a more natural language, thus simulating having a new language inside the language. That's my terminology, and I think others share this view too. – Didier A. Aug 12 '15 at 20:04
  • 1
    @didibus fair enough. though the first one doesn't express anything beyond the individual commands. That's why it's only chaining. But the second one does make sense as a whole thing. It expresses something more meaningful that just the individual commands. It has semantics. That's the main difference. The first one is not a domain specific language. The second one is. That's where I'd draw the line. – Gordon Aug 12 '15 at 20:56
  • 1
    @Gordon I admit the first one is semantically light, but I'd argue it still has semantics. I view semantics as something which has implications and relations. By virtue of SomeObject, Foo, Bar and Baz are related. Unless SomeObject is a random amalgam of unrelated properties, it is the beginning of a semantic relationship. What I set Foo to, will probably have an impact on what I set Bar to. If not, it's a poorly designed Class. Similarly, you can transform both interface to be non fluent, yet keep all the semantics intact: "SQLBuilder a; a.select(); a.from(); a.prepare();". – Didier A. Aug 12 '15 at 21:46
  • 7
    @Gordon Thus, in my view, semantics are not what makes an interface Fluent, because you can easily use the same semantics with a traditional OOP style interface using statements and semi-colons. I'd define fluent as Dave Fancher said: "A fluent interface is a specialized, self-referencing form of method chaining where the context is maintained through the chain." – Didier A. Aug 12 '15 at 21:49
  • The fluent interface allows us to provide a telescoping syntax to a builder, thus allowing very long and complex construction statements (dare I say, telescopic?) with arbitrary ordering of arguments. Resuscitating a design problem with the application of a second pattern precisely manifests a third, the [design pattern zealot](http://www.theserverside.com/news/thread.tss?thread_id=60542). – John Aug 18 '16 at 20:25
  • "Certainly [method] chaining is a common technique to use with fluent interfaces, but true fluency is much more than that.". "[Creating a fluent interface] entails designing an interface that reads like a DSL". https://www.martinfowler.com/bliki/FluentInterface.html https://en.wikipedia.org/wiki/Fluent_interface – User128525 Sep 15 '20 at 10:54
46

The idea behind a Fluent interface is that one can apply multiple properties to an object by connecting them with dots, without having to respecify the object each time. The idea behind the builder pattern is that unshared mutable objects are often easier to work with than unshared immutable ones, but it's much easier to reason about shared immutable objects than shared mutable ones. Thus, code can use an an easy-to-work-with mutable object to produce a "model" of a desired instance, and then use that to make an easy-to-share immutable object that holds the same data.

The two ideas can work well together, but are somewhat orthogonal.

Note that there are at least three ways a fluent interface can work:

  • By having each member of an instance return a new instance with the appropriate change applied.
  • By having each member mutate the instance upon which it is invoked and return that.
  • By having each member return an instance of a lightweight patch object which holds a link to either the thing being modified or the previous patch.

The last style requires that some action be taken to apply all the patches, but if the object being modified is large and many changes are necessary, it can minimize the amount of copying that's required.

anacron
  • 6,443
  • 2
  • 26
  • 31
supercat
  • 77,689
  • 9
  • 166
  • 211
  • 8
    Not sure I agree with your definition of Fluent Interface. It sounds like Method Chaining only. I won't downvote, but please see my answer for an explanation what Fluent Interfaces achieve. – Gordon Jul 30 '13 at 07:08
  • 1
    -1 due to incorrect/incomplete description of fluent interface, hardly relevant immutable/mutable objects with builder pattern and incorrect orthogonality claim. IMO, of course. – Creynders Jul 30 '13 at 09:17
  • 7
    Don't know why people criticized your answer, you're pretty spot on. Fluent is a pattern for adding method cascading to languages that don't have it, and combining cascading with chaining. I also don't see the critique of builder, mutability/immutability is one of it's major use case. Though it can be used for more things, like aggregating params across methods, and doing validation, etc. – Didier A. Aug 07 '15 at 02:04
  • Didier, what is wrong with having a couple of static methods for creating objects rather than a builder? I'm trying to work out if I really need a builder for my fluent objects that only have one or 2 construction sequences. – LegendLength Jul 13 '17 at 04:30