Java static imports + Fluent interfaces + Builder pattern= DSL

After having written nothing for a long time I am back to talk about an interesting bunch of java features. I am talking about DSL in Java, not as clean and powerful as in Ruby but, I think, very interesting for Java developers.

Static import

So, let’s start with static import, a nice Java feature introduced in its 5th version. Until Java 5, we could only import classes for using in our code, so that, instead of using something as ugly as java.util.List list= new java.util.ArrayList() we could simplify by importing the List and ArrayList classes and omit the package class in the creation and usage of the objects.

But, what happens when we want to use static methods or properties of other classes?

MyFunnyClass.myMoreFunnierMethod(param)
MyFunnyClass.NotSoFunnyMethod(param)

Our code gets cluttered by retyping the class part, when this shouldn’t be necessary. Wouldn’t it be nice if we were able to express ‘I want to use the following static methods in my class, and then use them as methods defined in our class’ ?

We are lucky, Sun engineers introduced the static import feature in Java5. So how do we use it? This is a piece of cake:

import static mypackage.MyClass.interestingMethod
...
interestingMethod("Look ma, I don't need referencing to MyClass!")

or we can use wildcards instead:

import static mypackage.MyClass.*
...
interestingMethod("Look ma, I don't need referencing to MyClass!")
otherInterestingMethod("Look ma, I don't need referencing to MyClass!")

It doesn’t look very useful for what we usually code, and used incorrectly, can derive in a fist of method calls that we don’t know where they come from. But this feature is going to be crucial for DSLs design in Java…

Fluent interfaces

Fluent interfaces are a way of designing interfaces that allows us to chain method calls, making our code more readable. So, what does it looks like?

Without fluent interfaces:

Person person= new Person();
person.setName("John");
person.setSurname ("Smith");
person.setPet(new Dog("Charly"));
person.setClothingStyle(ClothingStyle.CASUAL);

With a fluent interface API:

Person person = new Person().name("John").surname("Smith").pet(new Dog("Charly")).clothingStyle(ClothingStyle.CASUAL)

Fluent interfaces make our code look much better.

Using chained methods is as easy as returning the object instance (this) at the end of each fluent method:

public class Person{
...
  public Person name(String name){
     this._name=name;
     return this;
  }
...
}

Fluent interfaces are compatible with having accessor methods (set* and get*) in our classes. Basically, the goal is to ease the API usage and uplift the readability/expressivity of our code.
You can get more information about fluent interfaces in Martin Fowler Blog.

Builder Pattern

The previous two features look very interesting, don’t they? And it seems that both of them can be used to improve our code readability, and actually they do. But there is a last feature that takes advantage of them , we are talking about the Builder Pattern.

Quoted from the Wikipedia:

The Builder Pattern is a software design pattern. The intention is to separate the construction of a complex object from its representation so that the same construction process can create different representations.

In short, we are going to have an object that facilitates the construction of …other objects! This implies that such a pattern is only useful when we design interfaces for objects that we are going to build up many times with different parameterization or to designing interfaces.

I am the sort of person that prefers an example over loads of paragraphs explaining it , hence go carefully through the following code:

package test;

import java.util.Calendar;
import static java.util.Calendar.* ;
import java.util.Date;

public final class TimeUtil {

    public static DateEx now() {
        return new DateEx(new Date());

    }

    public static DateEx tomorrow() {
        DateEx date = new DateEx(new Date());
        return date.add(days(1));
    }

    public static DateEx yesterday() {
        DateEx date = new DateEx(new Date());
        return date.subtract(days(1));
    }

    public static TimeUnit months(int n) {
        return new TimeUnit(MONTH, n);
    }

    public static TimeUnit years(int n) {
        return new TimeUnit(YEAR, n);
    }

    public static TimeUnit days(int n) {
        return new TimeUnit(DAY_OF_MONTH, n);
    }

    public static DateEx date(Date date) {
        return new DateEx(date);

    }

    private static final class TimeUnit {
        private final int type;
        private final int size;

        public TimeUnit(int type, int size) {
            this.type = type;
            this.size = size;
        }
    }

    public static final class DateEx {

        private final Calendar date;

        public DateEx(Date date) {

            this.date = Calendar.getInstance();
            this.date.setTime(date);
        }

        public Date toDate() {
            return date.getTime ();
        }

        public DateEx add(TimeUnit unit) {
            date.add(unit.type, unit.size);
            return this;

        }

        public DateEx subtract(TimeUnit unit) {
            date.add(unit.type, -unit.size);
            return this;

        }

        public DateEx clearTime() {
            date.set(HOUR_OF_DAY, 0);
            date.clear(MINUTE);
            date.clear (SECOND);
            date.clear(MILLISECOND);
            return this;

        }

        public DateEx firstDayOfMoth() {
            date.set(DAY_OF_MONTH, 1);
            return this;
        }

        public String toString() {
            return date.getTime().toString();

        }
    }
}

No worries, I am going to explain each line of code, or at least the more interesting ones:

import static java.util.Calendar.* ;

This rings a bell, I hope. In this case, importing Calendar static fields allows us to use them as:

            date.set(HOUR_OF_DAY, 0);
            date.clear(MINUTE);
            date.clear (SECOND);
            date.clear(MILLISECOND);

We are building a date builder, so we need another class especialized in the construction of java.util.Date objects. This DateEx inner class for:

    public static final class DateEx {
    ...
   }

The key point here is that DateEx is a construction utility that uses fluent interfaces, so that we can chain methods calls to DateEx objects like:

DateEx dateBuilder= new DateEx(new Date()).firstDayOfMonth().clearTime()

and finally get the date object:

Date date= dateBuilder.toDate()

This code seems alright, yet did you notice what an ugly code we are using to note “now” ? new DateEx(new Date()) ??? What the hell is this? If I want to express “now” I want something that actually does it, and “new DateEx(new Date..” doesn’t at all. Luckily, we might define convenient methods for that sort of things:

    public static DateEx now() {
        return new DateEx(new Date());

    }

Now, if we import the now static method in our class we can rewrite the previous code as:

DateEx dateBuilder= now().firstDayOfMonth().clearTime()

This is the kind of code that makes me happy (Yes, I know…). Look at it, and at first glance, you realize “hey, he is clearing the time part of the first day of the current month”.

Furthermore, we can add a couple of convenient methods to our new little API:

    public static DateEx tomorrow();
    public static DateEx yesterday();

There is also a TimeUnit inner class that allows us to express time units in order to perform time operations to our DateEx objects. For example, what if we wanted to get 1 month and 10 days before the current date? We can do it with our TimeUnit classes and static util methods as:

dateBuilder.subtract(months(1)).subtract(days(10));

Cooler than using our good ol’ Calendar friend.

What kind of things can we do with this example API?

package test;

import static test.TimeUtil.*;
import java.util.Date;

public class Example {
    public static void main(String [] params){

        Date date= new Date();
        System.out.println (date(date).add(years(1)));

        System.out.println(now().toDate());
        System.out.println(now().add(days(2)).add(months(1)).subtract(years(1)).clearTime().toDate());
        System.out.println(yesterday()+" - "+now()+" - "+tomorrow());
        System.out.println(now().clearTime().firstDayOfMoth());
    }
}

Neat, it is not perfect, a lot of brackets are needed which only mess the code up, but as I see it, we have improved the expressivity of our code. In any case, my advice is to learn a new language like Ruby or Groovy, it opens your mind and teaches you different ways of doing things.

On the other hand, Java 7 specification is going to define closures for the Java language, so in the future we are going to be able to do more interesting things!

10 Comments

  1. admin:

    How can this method

    public Person name(String name){
    this._name=name;
    return this;
    }

    be compatible with existing accessors in a javabean? Do I need the setter method

    public void setName(String name) {
    this._name=name;
    }

    co-existing with the new one above? I wouldn´t like to count on two separate methods to do that. How’d be the getter like?

    Btw, if the bean fields start with a leading ‘_’, ain´t using this._field=field kinda superfluous?

    Good post.

  2. Mikel Alcón:

    Yes, you are right. You need getters and setters in order to be POJO “compatible”. This is the reason why I prefer using fluent interfaces only with Builder Pattern, for decoupling the construction facilities of the object from the object itself. Obviously having a name setter and a setName one is not very DRY, the comment was more about that, if you want, you can have fluent interfaces and POJO like methods (Yes, it is not very advisable)

    This type of methods are useful for human usage, not for frameworks like Hibernate,JSF, etc. where getters and setters are more suitable. As a summary, I would use fluent interfaces with Builder Pattern for construction and a POJO for the object/entity.

    Yes this._name is obviously not needed (I started with a ‘name’ property and I changed after, but I missed removing this :D)

  3. pabrantes:

    Interesting combination you suggest. Never had thought in that.

    Just as a reference for anyone interested in DSLs, another way of creating DSLs is to
    create a grammar using antlr and use that grammar to generate code.
    Although I know that is more complicated not to mention that solutions with generated
    code can sometimes be very “spooky” :-)
    Congratulations for the well written article.
    Regards,

    Paulo Abrantes

  4. Marcos Silva Pereira:

    You are right, brackets made the code less readable because they break the sequence. I am developing a tiny api to work with dates using the same strategy, but with different phrases:

    Date before = $(2).days().before().now();
    Date from = $(5).hours().from(aDate);

    Kind Regards

  5. prashant:

    Hi,

    Good thought proving article.enjoyed reading.

    Thanks
    Prashant Jalasutram
    http://prashantjalasutram.blogspot.com/

  6. Stephan Schmidt:

    Funny, I recently wrote about the same things.

    I’m not sure what DSL really means, when mixed with a base language. A real DSL would be it’s own language, but then Rails wouldn’t be a DSL also.

    I wrote about a fluent interface to Google collections: http://stephan.reposita.org/archives/2007/10/17/creating-a-fluent-interface-for-google-collections/

    and how to automatically create fluent interfaces from an Java interface with reflection:

    http://stephan.reposita.org/archives/2007/10/10/fluent-interface-and-reflection-for-object-building-in-java/

    I also hope that closures in Java 7 will move us in the right direction.

    Peace
    -stephan


    Stephan Schmidt :: stephan@reposita.org
    Reposita Open Source - Monitor your software development
    http://www.reposita.org
    Blog at http://stephan.reposita.org - No signal. No noise.

  7. Stephan Schmidt:

    @Marcos:

    I’ve been using the $() shortcut in Reposita Messages, as a lookup for i18n bundles and keys. System.out.println($( FILE_NOT_FOUND, file)) is easier to read than …(bundle.getMessage(…)). I’m not sure if in your case it would be more readable with days(5) and hours(3), the $() seems to me a try to rebuild the Ruby way with 5.times. It’s clean, but times(5) and days(3) is as readable and no need to extend Integer.

    Peace
    -stephan

  8. Mikel Alcón:

    Paulo: Antlr is a good tool, but I wouldn’t use it unless it is strictly necessary. When you build a external DSL you lost a lot of functionalities from the host language. Generally I prefer internal DSL. If you want to use Antlr you have to think it if it worth it. For many organizations is easier to develop a Java/Ruby/Groovy based DSL, which they can reuse their host language experience, than constructing a completely new language.

  9. Mikel Alcón:

    Stephan: Rather than using something so obfuscated as a method called $, I would rename it to something more clean:

    System.out.println(i18n( FILE_NOT_FOUND, file))

    for example. Anyone who reads this knows what the code is doing (I think it cannot be said the same for the $ method).

    BTW, good post about fluent interfaces.

  10. Scott Hanselman's Computer Zen - The Weekly Source Code 14 - Fluent Interface Edition:

    [...] Similar things are done in Java with their support for mixins, called Static Imports in Java 5. [...]

Leave a comment