Fluent Interfaces: Love Them or Hate Them?


The fluent interface is either loved or hated depending on the software engineering camp you belong to.  One of the problems with a fluent interface is gathering appropriate stack trace data from a production server.  Consider this code:

public class SupportPain {
   class Quote {
      void Buy() {
      }
   }

   class RFS {
      Quote getQuote() {
         return null;
      }
   }

   class Pricing {
      RFS getRFQ() {
         return new RFS();
      }
   }

   public static void main(String args[]) {
      new SupportPain().run();
   }

   public void run() {
      try {
         new Pricing().getRFQ().getQuote().Buy();
      } catch (NullPointerException ex) {
         ex.printStackTrace();
      }
   }
}

The above code would generate the following exception:

java.lang.NullPointerException
at SupportPain.run(SupportPain.java:24)
at SupportPain.main(SupportPain.java:19)

Which unfortunately generates a degree of pain when the issue is in a production trading system, and the trader is loosing money because the system is broken😦 So if you love fluent interfaces then remember to be sure you’ve coded for all eventualities. I remember to consider support issues

~ by mdavey on June 18, 2012.

7 Responses to “Fluent Interfaces: Love Them or Hate Them?”

  1. It’s nothing to do with fluent interfaces, just a bunch of one-method classes, which are used in obscure way. If you use a temp variable for every returned value – situation will be much more clear, something one can not do with fluent interfaces. Moreover, in this example one can’t log or debug returned values from every method, unless he does this inside of every class.

  2. Andrey — a good solution for logging (and debugging simple problems) with fluent interfaces is to use AOP (aspect-oriented programming).

    It’s certainly possible to go overboard with fluent interfaces by attempting to use them *everywhere*; however, they also provide a great way to simplify and maintain code by providing a clean, easy-to-use DSL which wraps some more complex functionality (e.g., Fluent NHibernate). Add AOP on top of this and you’ll have the flexibility you need (for development/debugging) without complicating your fluent interfaces or needing to rewrite/modify code just to examine values for testing.

    Matt — My preferred solution for the problem you’ve proposed: Design by Contract (“Code Contracts”). It’s easy to add contact specifications into your code while you’re writing it, and doing so allows automated tools (like the code contract checker in Visual Studio, or Google’s cofoja project) to find the majority of simple bugs at compile-time — so they never make it into production.

  3. I’m sure there are a number of fluent anti patterns.
    Used wrong fluent can make any task more difficult; it moves away from built in languages features so you have to learn each fluent grammar a new.
    It can add redundancy as the code used could be just as succinct using built in language features.
    It can introduce side effects if you take a reference to a method chain with mutable state.
    I’ve come across several other abuses too.

  4. Most fluent interfaces I’ve seen are only used in conjunction with the builder pattern — where each step configures an object, and the last step executes or compiles it (e.g. building an object or configuring a query).

    I don’t think a fluent API is valid for your example… it has only produced a law of demeter violation.

  5. Agree with the previous comments that the given code is not an adequate example of fluent interface usage. It has rather to do with the problem of exception swallowing.

    However, a solution based on smth like Scala’s Option.getOrElse could do in some cases in order to achieve safe navigation with fluent interface.

  6. I understand the point you are making – but as people have mentioned, this isn’t anything like a fluent interface, and certainly you would never use a fluent interface for something like this.

    In any situation, a null violation is very difficult to track down – and as you point out, it’s worse in a chain of dots… However, this isn’t just an example of a class of problems… it’s the _only_ problem of this nature.

    So the real solution is to solve nulls – we use a code weaver to add in null checks for all parameters and return values that are not attributed to be null. So – you are essentially guaranteed that can’t happen – in your example above our stack trace would have “getQuote” in it [well, actually, it wouldn’t, it would have “quote” – because the word “get” adds nothing]

  7. The actual problem is constructor calls not showing up in the stack trace. The second problem is Java implementing null pointers like C.

    Try C++.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: