Wednesday, August 19, 2009

Book Review: Enterprise Integration Patterns

26636021 I just finished reading Enterprise Integration Patterns written by Gregor Hohpe and Bobby Woolf. This book follows the same concept used by Martin Fowler and his marvelous PoEAA book, but obviously focused on integration patterns. Although the title is somewhat misleading, this book fully concentrates on message based architectures as opposed to other integration styles.

I'm somewhat new to message based architectures. By reading this book, I learned a lot of the concepts around messaging and showed me how to make the mind shift that it requires. It also made me realize some important things about SOA and DDD as well.

The introduction and the first chapter discuss the various needs of integration solutions. The first chapter also provides a nice example of a message based integration architecture. Don't miss out on these opening chapters as they clearly opened my eyes about some of the aspects of messaging.

Chapter two describes the different approaches for integrating applications, like File Transfer, Shared Database, Remote Procedure Invocation and of course Messaging, with all their advantages and disadvantages. This is the only chapter that discuss other integration styles, after which messaging is discussed throughout the rest of the book.

The third chapter introduces the six root messaging patterns (Message Channel, Message, Pipes and Filters, Message Router, Message Translator and Message Endpoint). The subsequent chapters take a more detailed view on each of these six root patterns. Except for Pipes and Filters, every fundamental messaging pattern leads to its own chapter that provides a concise reference of the respective supporting patterns.

As with most pattern books like these, don't expect to see lots and lots of code although this book does contain some technical stuff. Code snippets are shown at the end of each pattern, mostly on JMS and MSMQ (occasionally TIBCO and WebSphere MQ). There are also three separate interlude chapters that provide one or more examples about some of the patterns discussed in earlier (or sometimes upcoming) chapters. So it could be worse.

The book can be read from cover to cover, but I'd certainly not recommend it. Although concisely written, this piece of work is not something you want to read bedtime stories from (although it has occasionally put me to sleep). As I already mentioned, I'm fairly new to message based  architectures. I read the first six chapters, skimmed through the chapter on Message Routing and picked up again by reading the chapters on Message Transformation and Messaging Endpoints. The latter is probably of the most practical use as this chapter discusses how to integrate an application with a messaging system.

I have a feel that I'm going to be referencing this book a lot in the near future. ;-) This book, like the PoEAA book, definitely falls into the category of reading it more than once, which is certainly worth the effort. I really enjoyed reading this book and I welcome it to my growing list of favorite books.

Till next time

Saturday, August 01, 2009

Fluent Domain Methods

In my last post, I talked about a Generic Expression Builder class for easily creating domain entities through expression builders. This generic base class takes away some of the burden while developing these expression builder classes.  Expression builders are generally useful inside the domain when you need to create and set up a complete aggregate root from scratch, not to say that expression builders aren't useful in other parts of an application (e.g. creating message objects, DTO's, etc.).

Another place where a fluent interface can add value is for implementing behavior on a domain entity. Taking the same example from my previous post, where we have a domain class named Document with the name of the author, a title and one or more associated tags. Suppose we have a command that needs to add a new Tag to the existing list of tags for a particular Document. We usually end up with code like this:

public class Document
{
    var IList<Tag> _tags = new List<Tag>();

    ...

    public void AddTag(String name)    
    {
        var newTag = new Tag(name);
        _tags.Add(newTag);
    }
}

The usual mistake I see a lot is to let the AddTag method directly take a Tag object. However, in this case the Document class is the aggregate root where Tag is merely a value object that lives within the boundaries of its aggregate root. This means that the aggregate root is responsible for creating instances of a Tag (also check out this post from Udi Dahan).

Lets make this code a bit more fluent. In my previous post, I provided a separate expression builder for creating new Tag objects. This TagBuilder is already used by the expression builder that creates Document objects.

public interface ITagBuilder
{
    void Named(String name);
}

public class TagBuilder : ITagBuilder
{
    private readonly Action<Tag> _afterBuildAction;

    public TagBuilder(Action<Tag> afterBuildAction)
    {
        _afterBuildAction = afterBuildAction;
    }

    public void Named(String name)
    {
        var tag = new Tag(name);
        _afterBuildAction(tag);
    }
}
Now lets reuse this builder class for our domain method that adds a new Tag for a Document. This is how the AddTag method is implemented:
public ITagBuilder AddTag()
{
    return new TagBuilder(newTag => _tags.Add(newTag));
}

And this is how the calling code looks:

document.AddTag().Named("Science"));

I have to admit that it does involve some overkill for this simple example. However, the code becomes a lot more clear when you have to provide a couple of more arguments to a domain method. Again, not everything is a nail for this shiny hammer. But it does bring some nice, readable code when needed. Here's another example that attaches the data of a file to a Document:

document.Attach()
    .FileWithName("The Universe in a Nutshell.pdf")
    .AndData(new Byte[] { ... });

The fact that we can just reuse an existing expression builder is also a clear advantage.

Till next time