Example of creating a model object that represents a customer:
Customer customer = createCustomer.named("Bob").that(bought.item(CompactDisc).on("02/17/2006"));
Example of querying a list of customers:
List<Customer> question = questionThatAsks.whichCustomers(bought(anything(), between("12/31/2006", "01/01/2007"))).ask(customers);
Full code examples are available files section of the home page.
My team has created two comparable Fluent APIs to help us build and query model objects, and our productivity has increased substantially from it. It has allowed us to program at a very high level and in the terms of our business domain. There are trade-offs involved. For instance, it is difficult to look at a individual methods and understand how they fit into the system. You will likely have methods named 'with' and 'and' that do very little if any work. These methods exist entirely for the sake of readability. Fortunately, it is very easy to learn to use Fluent APIs from examples.
Creating Fluent APIs is another story all together. It is not difficult or complex, but it is a radical departure from tradition programming paradigm. For this reason it often takes some mental acrobatics to design a new Fluent API, but it gets easier with time. I believe, though, that this learning curve is partly because common patterns pertaining to creating Fluent APIs have not adequately been formalized and documented. These techniques have been used by visionaries for many years particularly in the Ruby community (often called DSLs). However Fluent APIs are just starting to gain popularity in the mainstream Java and C# communities. One reason that this movement was started in the dynamic language communities is that the flexibility of such languages makes creating elegant Fluent APIs much easier. Part of the reason that Fluent APIs are starting to catch on in the Java community is that Java 5 introduced some features that, when used together, make such expressive APIs both possible and practical. Static imports, generics and enums play crucial roles in achieving English-like readability.
The success and productivity that I have experienced using Fluent APIs in Java has given me a new appreciation for Java. This appreciation is not for Java as a solution for real world problem, but as a means of creating the tools necessary for solving real world problems.
Popular tools using Fluent APIs:
- JMock (For scripting expectations)
- Guice (Binders)
- JAX-B (Fluent API Plugin)
No comments:
Post a Comment