I have been wanting to pull some thoughts together related to my experience of a project I’ll be releasing in a few months that has pulled from all of these hats. The decision to gradually wade into these waters was driven largely by the increased complexity of the behaviors required by this mission-critical system. There were some remarks made either in useful blogs, forums or other venues along the way that would make a particular quandary seemingly less monumental – my hope is that perhaps there are some of those remarks made here to contribute to others possibly investigating an architecture that might benefit from these paradigms.
First, system infrastructure:
- Monorail MVC web framework
- Rhino Service Bus for messaging
- Windows Services hosting the domain and reporting
- Sql Server 2005 Domain Event storage (the ‘command’ side)
- NHibernate OR/M helping the Reporting Model that supports the web UI and domain services
- Driven by TDD/BDD specs using homegrown BDD artifacts
Do Not Skip The Ubiquitous Language
It was somewhat ironic that I felt like the part about “Ubiquitous Language” in Eric Evans’ book was boring. This is mostly due to the fact that I work alone with A subject matter expert that gives requirements out of a gerbil feeding tube for this project. Still my failure to get what he is driving at really bit me and made my system far too complex to understand because a system without a behavioral emphasis is necessarily procedural. Even with neato patterns and good OOP the system still felt like it was programmer-centric. It wasn’t until I watched Udi Dahan talk about Making Roles Explicit that I realized what was lacking to help us succeed. This in conjunction with Greg Young’s assertion that a domain consists of behavior, not shape, really made me see that my state-based, data-driven domain needed refinement to scale and adapt.
Specifically, I started thinking how the lab or field construction worker thinks. For example, when they pour concrete into a designated area they Complete The Placement. Yet in the system I had the operation that was the entry point for a Placement into the system called “AddPlacement”. If you were to ask the construction guy “Have you added that Placement yet?”, he’d just say “huh?”. This sounds trivial but the simple movement away from collection-based or procedural naming conventions revolutionized how my specs were driven. This wasn’t just syntactic sugar stroking a geek for cheap goose pimples, this was improved structure and behavioral concerns.
When moving to an Event Driven Architecture I believe the majority of growing pains come from this shift in reasoning about what is actually being done in the system from the user’s perspective versus how it is being implemented by code. A code smell to me now includes the presence of collections-type semantics when defining my events. “AddThis”, “DeleteThat”, “ReplaceThis” – these are the kinds of language that make me wonder if I am thinking too much like a developer working with data. When I fall into this, I pull back and try to reconsider what is really being done for the business. Many answers or suggestions that come from people I have learned to respect are usually reframing the problem into a more semantically correct question, leading to a more meaningful answer. A good example of this was the recent debate about “soft deletes” bandied about in the blogosphere – Udi Dahan weighed in with advice that I felt remembers the original problem; namely, how would a user of the application define the operation?
Relying on domain events for building up state in the domain is a lot like installing bright lights in an apartment that you need to clean thoroughly to get your deposit back– suddenly you see the parts you have been overlooking. Changing state in a system that is using event sourcing seems to reveal these little shortcuts of thinking that open up doors of opportunity for both the end user and you. Making transitions in the system explicit with meaningful names derived from the business vernacular, not the technological, suddenly makes intent clearer and the paths through the system clearer – something Event Driven architectures need.
Today I found myself slipping back into events like “ElutriationCalculatedEvent”, “WeightPassChangedEvent” and so on. When I started using the vernacular of the docs my business people are using,though, I used names like “ElutriationDeterminedEvent”. This seems trivial, but no one in a lab “Calculates” the material left over from washing – they “determine” it and that informs other observations. When I think along these terms, my code inevitably becomes richer and my conversations more natural with the business people. As an aside, I felt a recent post by Russell Ball really hit the nail on the head with the programmer’s responsibility for concise language in this regard.
05-06-2010 12:50 AM