Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Sunday, January 16, 2005

HiveMind In Chains

The Gang of Four's Chain of Command pattern is a very useful one; we all use it all the time whether we realize it or not. David Geary has just started using it in anger with JSF, starting with the Jakarta commons-chain framework.

Chain of Command is very simple; you have a list of objects that all implement a particular interface. You simply invoke the same method on each object (in a specific order), until one object indicates that the chain is complete. Typically, the methods return a boolean, and a return value of true indicates that the chain has completed.

HiveMind 1.1 already includes an implementation of the Adapter pattern, so it was time to create Chain of Command. This takes the form of a general purpose ChainBuilder, service and a ChainFactory service used to build service implementations.

What differentiates HiveMind's Chain of Command from other implementations is that command interface is arbitrary and application-specification. There's no Command interface; the implementation generated on-the-fly adapts to whatever interface you already have. Your interface may have any number of methods, with any return type (including void), parameters, and exceptions. In 132 lines of (non-comment) code.

Using the ChainFactory, the chain of command becomes just another service implementing the interface, ready to be injected into any other service that needs it.

Tapestry 3.1 already has a number of command chains; it will be nice to refactor that code around this new functionality.

I think a good number of developers out there are aware of many of the Gang of Four's design patterns ... but they have trouble seeing how those patterns fit into their own applications. In the Gang of Four designs, the necessary objects are always instantiated and connected to each other, but it's left as a puzzle to the reader to deduce how they got that way.

In my terminology, the Gang of Four patterns focus on the production state of the system and of the individual services, and ignore the construction state, just as they ignore the destruction state. To be honest, I don't have a copy of the book handy, and I'm sure some of the examples do get involved in this issue (and some of the patterns are themselves creational).

Regardless, HiveMind takes this bull by the horns, because it's largely about the construction state. Using a combination of a HiveMind configuration and a service implementation factory, it becomes quite natural to have a configuration that describes those production state relationships, and create a service that encapsulates the behavior with those relationship in place. For chains, the configuration point describes the commands and their order, and the service implementation factory builds a service implementation that invokes the methods on the commands for you.

1 comment:

dh_honig said...

I'm wondering though about trying to apply this to business processes. It probably is way too complex but would you ever want to have chains of chains?.....I'm musing in my head about this and trying to find real world examples. But it would seem to me in a robust chain implemenation or business process engine(a CoR itself) a chain step could consist of another chain. And chains themselves could be reused across various processes. I suppose the usefulness of this is limited to the context of what you are building. You can't really add too much functionality like this in something like HiveMind or Spring without bloating its purpose, because also in the same breath you have workflow, which is not always linear?

But using chains are not a new idea. I've used this strategy on many projects, particularily in projects that deal with assembling content such as SOAP responses. In fact even Cocoon relies on CoR at its heart.