Sunday 27 October 2013

Trainwreck vs. Method Chaining

I thought it worth while to expound on the differences between a train wreck and method chaining.

Whereas a trainwreck is a bad idea, method chaining is an excellent idea. This blog will try to explain why these two are polar opposites on the good/bad scale, even though the syntax differs very little.

Trainwreck


A trainwreck is a bad idea. It provides an Object A with in depth knowledge of several other objects. Knowledge that should be contained in the individual objects instead of Object A.

In code it would look like follows:

public class A
{
    public void someMethod(B b)
    {
        b.getC().getD().getE().doThing();
    }
}

A Trainwreck breaks the Law of Demeter[1] (and everyone knows, if you break a law, you have to go to jail).

A solution would be to just tell B to do it, and let it figure it out.
public class A
{
    public void someMethod(B b)
    {
        b.doThing();
    }
}

Method Chaining


Method chaining is an excellent idea. The methods used always return the Object itself. It's a good way of constructing an Object without having to resort to multiple different Constructor methods with varying (large amount of) parameters.
public class Person
{

    private long id;
    private String firstName;
    private String lastName;
    private String address;
    private String telephone;
    private String title;

    public Person(long id)
    {
        this.id = id;
    }

    public Person setFirstName(String firstName)
    {
        this.firstName = firstName;
        return this;
    }

    ...
}

public static void main(String[] args)
{
    Person mrBear = (new Person(1l)).setFirstName("B.").
              setLastName("Bear").setTitle("Mr.");
}

Method Chaining does not break the Law of Demeter[1]. It doesn't even talk to friends (in this case), but only to itself.

Here I have used a simplified example. Mostly you'd create a PersonBuilder to make Persons.[4]

For some great uses of method chaining check out [2] and [3].

References

[1] Glossary
http://randomthoughtsonjavaprogramming.blogspot.nl/p/glossary.html
[2] FluentInterface
http://martinfowler.com/bliki/FluentInterface.html
[3] Expression Builders
http://martinfowler.com/bliki/ExpressionBuilder.html
[4] Too Many Parameters in Java Methods, Part 3: Builder Pattern
http://marxsoftware.blogspot.nl/2013/10/too-many-parameters-in-java-3-builder-pattern.html

2 comments:

  1. I see where you are going but I don't completely agree with the example you used for method chaining. A setter normally is a mutator and would not return an object unless you are using the builder pattern. Unless you explictly indicate that you are using this pattern, your intent would be potentially confusing for someone coming back to look at the code.

    ReplyDelete
    Replies
    1. Agreed. It's a bad example. I shall write a blog post about a proper builder pattern. (Though Martin Fowler beat me to it. ;-) )

      Delete