Wednesday, January 19, 2011

Stardate 2011.19.1: Domain Events - Powerful, Stupidly Named

Today, I thought I'd point out something that is terrifically obvious: Domain events may be the strongest concept to come to domain-driven programming since the ubiquitous language. I almost always have an object of type DomainEvents these days because they're just so useful. They become a kind of repository for the different things that can happen in the domain that really have no other place - see Udi Dahan's website for more information about the concept of domain events.

Also, this is probably the worst name for a type in the history of mankind, and might be a mistake to have the object at all. The reason for this is that, like my rant against Commons projects, it often becomes a kind of repository for trash that just needs to be maintained over time. There are sometimes Action<T>s in it, which is a mistake, but also it is often a static class that just has the different possible domain events in it that can be raised statically. This makes it difficult to test, but there's also something more obvious: There's virtually no ubiquitous language which contains the concept of an explicit DomainEvents object in it. 

This is pretty obvious, however, and does not take away at all from the usefulness of the concept. Often, we require a place in the domain where we can just do different things that aren't necessarily part of the normal flow of execution of the business domain. For example, when filing a legislative bill, there are a crapton of things that can happen before the bill even gets into the first committee. However, there's no explicit, "Here's what's going to happen every time!" You can't necessarily model it effectively as a function that follows another function, e.g. if you have a SendToCommittee function, you can't necessarily prefix it with all of the functions that may happen before it goes to committee - there are just too many possibilities!

So how do you handle it? The best way (in my opinion) is basically with an event. There are many different ways to implement events in most programming languages. Since I'm a .NET developer exclusively, I'm going to talk about developing domain events in .NET, and C# in particular. I have no fuss with VB development, nor VB developers, but I'm just not familiar enough with it to be able to talk about it intelligently.

The standard DDD way of handling domain events in .NET uses the weak-eventing pattern. This is a pattern where you have a list of WeakReferences to actions. These actions get executed if they're valid references, or are skipped if they are not. That then becomes your domain event. It has to be a list of WeakReferences due to technical issues with subscribing causing a hard reference to stick around when it probably shouldn't - perhaps because the objects that have hooked up to the event would otherwise have gone out of scope.

My next post will have more useful content. I just wanted to point out that having an explicit type called DomainEvents is probably not the right way to go. In the next post, I'll discuss how I typically handle it, and why I think it's stronger and better OO design.

No comments:

Post a Comment