Strengthening your domain: The double dispatch pattern

Previous posts in this series:

It looks like there’s a pattern emerging here around encapsulation, and that’s not an accident.  Many of the code smells in the Fowler or Kerievsky refactoring books deal with proper encapsulation of both data and behavior.  In the previous post, we looked at closure of operations, that when an operation is completed, the aggregate root’s state is consistent.

In many anemic domain models, the behavior is there but in the wrong place.  For the DDD-literate, this is usually in a lot of domain services all poking at the state of the domain model.  We can refactor these services to enforce consistency through closed operations on our model, but there are cases where this sort of domain behavior doesn’t belong in the model.

This now begins to be difficult to reconcile.  We want to have a consistent model, but now we want to bring in services to the mix.  Do we now forgo the concept of Command/Query Separation in our model, and just expose state?  Or can we have our cake and eat it too?

Bringing in services

The last example looked at fees, payments and customers.  When a payment is recorded against a fee, we re-calculate the balance:

public Payment RecordPayment(decimal paymentAmount)
{
    var payment = new Payment(paymentAmount, this);

    _payments.Add(payment);

    RecalculateBalance();

    return payment;
}

private void RecalculateBalance()
{
    var totalApplied = _payments.Sum(payment => payment.Amount);
    
    Balance = Amount - totalApplied;
}

The problem comes in when calculating the balance becomes more difficult.  We might have a rather complex method for calculating payments, we might have recurring payments, transfers, debits, credits and so on.  This might become too much responsibility for the Fee object.  In fact, it could be argues that the Fee shouldn’t be responsible for how the balance is calculated, but instead only ensure that when a payment is recorded, the balance is updated.

We have several options here:

  • Update the Balance outside the RecordPayment method, with the caller “remembering”
  • Use a BalanceCalculator service as part of the RecordPayment method

I never like a solution that requires a user of the domain to “remember” to call a method after another one.  It’s not intention-revealing, and tends to leave the domain model in a wacky in-between state.  For many domains, this might be acceptable.  But with more complexity comes the issue of trying to sort out what scenarios are valid or not.  When a test breaks because an invariant is not satisfied, that’s a clear message that something broke the domain.

But if we leave our domain in half-baked states, it becomes much more difficult to decipher what to do when we change the behavior of our model and tests start to break.  Are the existing scenarios supported, or are they just around?  In the case of the latter, that’s where you start to see more defensive coding practices, throwing exceptions, gut-check asserts and so on.

So we decide to go with the Aggregate Root relying on a Domain Service for balance calculation.  Now we have to decide where the service comes from.

For those using a DI container, you might try to inject the dependencies into the aggregate root.  That leads to a whole host of problems, which are so numerous I won’t derail a perfectly good post by getting into it.  Instead, there’s another, more intention-revealing option: the double dispatch pattern.

Services and the double dispatch pattern

The double dispatch pattern is quite simple.  It involves passing an object to a method, and the method body calls another method on the passed in object, usually passing in itself as an argument.  In our case, we’ll first create an interface that represents our balance calculator domain service:

public interface IBalanceCalculator
{
    decimal Calculate(Fee fee);
}

The signature of the method is important.  It accepts a Fee object, but returns the total directly.  It doesn’t try to modify the Fee, allowing for a side-effect free function.  I can call the calculator as many times as I like with a given Fee, and I can be assured that the Fee object won’t be changed.  From the Fee side, I now need to use this service as part of recording a payment:

public Payment RecordPayment(decimal paymentAmount, IBalanceCalculator balanceCalculator)
{
    var payment = new Payment(paymentAmount, this);

    _payments.Add(payment);

    Balance = balanceCalculator.Calculate(this);

    return payment;
}

The intent of the RecordPayment method remains the same: it records a payment, and updates the balance.  The balance on the Fee object will always be correct.  The wrinkle we added is that our RecordPayment method now delegates to a domain service, the IBalanceCalculator, for calculation of the balance.  However, the Fee object is still responsible for maintaining a correct balance.  We just call the Calculate method on the balance calculator, passing in “this”, to figure out what the actual correct balance can be.

Wrapping it up

When a domain object begins to contain too many responsibilities, we start to break out those extra responsibilities into things like value objects and domain services.  This does not mean we have to give up consistency and closure of operations, however.  With the use of the double dispatch pattern, we can avoid anemic domain models, as well as the forlorn attempt to inject services into our domain model.  Our methods stay very intention-revealing, showing exactly what is needed to fulfill a request of recording a payment.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in Domain-Driven Design. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://bogdanbrinzarea.wordpress.com Bogdan

    Hi Jimmy,

    How about using domain events instead of double dispatch?

    Bogdan

    • Ad

       In a perfect world, I think constructor DI would be the best option, but given technical limitations (ie how ORMs handle non-default contructors, etc) I think the method injection is the best, simplest approach. I’d agree with @Krzysztof –this is Strategy Pattern…

  • http://kozmic.pl Krzysztof Kozmic

    Perhaps I missed something, but it feels to me the pattern you’re describing is called strategy rather than double dispatch.

  • Dave

    Have to agree with Krzysztof here, doesn’t really feel like double dispatch. Maybe if the BalanceCalculator was in turn calling back into the Fee object, to eliminate some conditional logic for instance. Thoughts?

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Bogdan

    I’ll touch on that in a future post, but domain events are usually used to communicate across aggregate roots in a single bounded context, that AREN’T otherwise related.

    @K2

    The double dispatch part of the pattern here is that instead of the caller being responsible for pre-calculating or post-calculating the balance, I use the service and pass in “this”. I could have used a concrete class as the calculator, that’s not the important piece.

    Here’s the non-double dispatch way of doing it:

    fee.RecordPayment(100m);
    var balance = balanceCalculator.Calculate(fee);
    fee.Balance = balance;

  • http://blog.coreycoreycoogan.com corey coogan

    Great series of posts here Jimmy. I’m guilty of typically injecting the IBalanceCalculator in the constructor, which comes with some hassles as you eluded to.

    I like the idea of passing the IBalanceCalculator to the method that needs it, but that raises the question of how to resolve that dependency? We are now requiring the caller to know how to resolve the IBalanceCalculator, so I’m wondering how you handle that?

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Dave

    The balance calculator is calling back into fee object, to get all the payments for example. The key here is that the user of Fee does not have to keep the balance updated, or whatever else Fee needs to do to stay consistent.

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @corey

    Yes, but that’s OK. It’s typically application services doing the top-level coordination anyway.

  • http://blog.coreycoreycoogan.com corey coogan

    @jimmy

    So does that mean your IoC container is injecting that dependency into your App Service or are you newing one up? As far as testability goes, injection seems better but are we now at the same place we were if we used DI to satisfy the domain object in the first place?

  • http://www.adverseconditionals.com Harry M

    I’d actually really appreciate an article on the pitfalls of injecting services into entities. It seemed like a good idea to me when Fabio posted that it was finally possible with NH.

    http://nhforge.org/blogs/nhibernate/archive/2008/12/12/entities-behavior-injection.aspx

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @corey

    Yep, DI always instantiates app services. In fact, it instantiates our controllers, so we never really need to worry about anything except our direct dependencies.

    @Harry

    np, I’ll get something in the queue. It’s possible and easy now, but I still feel far from desirable.

  • Henning Anderssen

    Why name it double dispatch, when it really is just method injection instead of constructor injection.

    What are your thoughts on injecting dependencies that uses other services, such as repositories, email services, application services, etc? When doing any kind of DI into your domain entities, it becomes really easy to go down that path where your entities uses external resources. I think that would cause a whole slew of problems, including making testing/mocking harder. It means one more thing to stub out.

    On my current project we are in exactly this situation where we’re considering method injection, because the logic has to be reused several places, although without the need for external resources.

    What about making the method static and directly using the static calculator in the RecordPayment method?

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Henning

    It’s double dispatch because it’s the double dispatch pattern, not method injection. Method/property injection means that my DI container sticks stuff into my entity, which I most definitely DON’T want. It also means that my container is now responsible for the entity construction, which I again don’t want.

    Making the calculator static means I now have a hidden dependency in RecordPayment. Why not just make it explicit in an intention-revealing interface? Stubbing is not a problem, as I no longer care about _how_ the balance is calculated when testing the Fee object. I only care _who_ calculates the balance. I can then test balance calculation in isolation.

  • http://www.lostechies.com/members/derick.bailey/default.aspx derick.bailey

    i like the premise behind what you’re saying, and I like the use of double dispatch for the core scenario you’re describing.

    to get nit-picky for a moment, though, (and yes, i know this is a blog post, not a real world app :) it seems to me that you’ve missed out on an opportunity to model the domain better. you’re dealing with customers, fees, balances, payments… but you have missed an opportunity to make this a little more explicit: accounts.

    if you would create an account for the customer, as an aggregate root, then you would not have to violate encapsulation by putting the balance calculation in the fee object. it doesn’t belong there. a fee is more of a data-to-be-acted-upon object and the double dispatch usage in this case feels like a workaround for an anemic model – exactly what you’re trying to avoid!.

    the account object should do the balance calculation a payment is made, and the IBalanceCalculator should be used by the account entity’s RecordPayment method in a double dispatch manner.

    of course, that’s just my opinion. :)

  • http://andyhitchman.wordpress.com Andy Hitchman

    I’d also like to understand the pitfalls on injecting services into entities via the constructor or optional properties. I’ve found this to work quite well on previous projects. What have I missed?

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Derick

    So the crappy thing about canned DDD models is that they’re canned, and you can pretty much invent any scenario now. If there is no such thing as an “Account” in this domain (which, in the real life example, there aren’t), then this would likely confuse my domain experts. But had there been an Account in this domain, I’d definitely agree.

  • Jak Charlton

    I’m not comfortable calling this double dispatch either (like a few others)… It lacks the “double” bit, ie the entity doesn’t pass itself back into the supplied calculator.

    This is really Strategyor method passing

    Contrast with an old post of mine around Specification and DD http://devlicious.com/blogs/casey/archive/2009/03/02/ddd-the-specification-pattern.aspx

  • http://simon-says-architecture.com/ Szymon Pobiega

    Some time ago I wrote a similar post advocating double dispatch as *the* way of inverting dependencies on the boundary of domain model. Unfortunately it is currently in Polish, so I won’t quote it;)

    Double dispatch is even more important when dealing with infrastructure services. In case of your BalanceCalculator putting it in the entity at least don’t break the conceptual model (it is bad for other reasons). In my case (EmailSender) putting the service in the domain entity mixes two very distinct responsibilities (model and infrastructure) and lifecycles.

    My own rule of thumb is use Domain Events (as desscribed by Udi) as a preferred way of IoC when interaction can be made one-way. If it can’t, I use double dispatch.

  • http://simon-says-architecture.com/ Szymon Pobiega

    Quick node: the last pingback points to the translation of the post I mentioned in my previous comment.

  • http://www.adverseconditionals.com Harry M

    @Szymon if the domain event is two way you can get an event arg passed back with the result using Udi’s pattern

  • http://www.adverseconditionals.com Harry M

    I mean ‘as a result’ rather than ‘with the result’. Obv.

  • http://simon-says-architecture.com/ Szymon Pobiega

    @Harry but this kind of usage obscures the intent of the event pattern. I would use double dispatch in this case, because using event and returning the result would leave me in situation that I don’t know which of the handlers should set the result and what if more than one want’s to do so.

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Jak

    Balance = balanceCalculator.Calculate(this);

    ? This looks like the very definition of DD.

    Granted, a lot of the existing material around DD is focused on C++ and the visitor pattern.

  • pat terne

    “Balance = balanceCalculator.Calculate(this);
    ? This looks like the very definition of DD.”
    Does it? What’s your definition of double-dispatch?

    Double dispatch is an extension of virtual calls (which can be seen as a single-dispatch), where the concrete implementation of a method call depends on two receivers. (A virtual call dispatches a method based only one the instance it’s called on, hence the “single” dispatch).

    Example: I have Geometry objects: Triangle, Square, Circle.
    If I write 3 methods to compute intersections (Tri & Square, Tri & Circle, Square & Circle) and then the correct one is automatically called when I do:
    Geometry g1 = new Triangle();
    Geometry g2 = new Square();
    g1.Intersect(g2);
    This is a double dispatch (unsupported in most popular languages, although you can create your own “dispatchers”).
    What wikipedia has to say about it: http://en.wikipedia.org/wiki/Double_dispatch

    Extracting the logic to compute the balance to another service looks a bit more like Strategy to me (although here you don’t aim for the real benefits of the Strategy pattern).

  • http://www.adverseconditionals.com Harry M

    @Szymon. For different events, different treatments of the args may occur (e.g. each handler might process the args individually like a pipeline, or you have a Chain of Responsibility to decide which handler to use).

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @pat

    Maybe I’m being obtuse here, but I’m using the definition of Greg Young, Jeremy Miller et al before me. The RecordPayment requires two objects to complete, and the calculator needs the first object to work. I’m not drawing vertices or printing objects, which is what most examples show. This is the intent for what I’m showing:

    http://c2.com/cgi/wiki?DoubleDispatchExample

    It’s not strategy exactly, as it’s a specific interaction pattern for a single operation. Maybe there’s another name for this pattern then, as strategy is about multiple implementations of a calculator (which is not the case here).

  • http://www.lostechies.com/members/derick.bailey/default.aspx derick.bailey

    FWIW – i don’t see how this isn’t double dispatch…. jimmy is passing a service into the a method, and then passing “this” into that service. if that’s not double dispatch, then what is?

  • http://richarddingwall.name Richard Dingwall

    I’ve used double dispatch before both for recovering type information lost via polymorphism (e.g. Pat’s Triangle Circle Square example) and for injecting services into domain entities (this blog post).

    It is the same pattern, just two different examples of what you can do with it.

  • David Fauber

    Attn: patternistas…no-one (seriously) cares what he’s calling the pattern

  • http://twitter.com/dbrock Daniel Brockman

    Double dispatch is about polymorphism, so if you’re not talking about polymorphism, then you’re not talking about double dispatch, as far as I’m concerned.

    (Just my two cents.)

  • Ralph

    Oh, no. Take it from an old c++ hacker. This is most certainly double dispatch. It doesn’t matter if there is polymorphism or not. There are two calls needed to complete the true task at hand.

    Now some people say that this is a strategy pattern. Well, not quite. Normally, strategies are determined at construction time, stored for the lifetime of the object and used consistently throughout the object lifetime. The example shown is passing an implementation to be used immediately and exactly once.

    Also, I would not consider the example to be method injection either, because such injector methods normally store the reference being passed and that reference is (normally) used for the remainder of the object lifetime. I would think that method injection more similar to strategy pattern. Furthermore, constructor injection is probably closest to a strategy, because dependencies are set at construction time.

  • http://www.pettys.name Jason Pettys

    Great post, Jimmy — very helpful stuff.

  • Johan
  • Jason

    I think some posters (myself included, initially) got mixed up between the “double dispatch” and “dynamic dispatch” concepts, which are often, incorrectly, used interchangeably.

    In my decades-long quest for dynamic dispatch, I forgot that double dispatch was even a worthy goal. Thanks, Jimmy!

  • Dave

    Just my $0.02: You could have the parameter to IBalanceCalculator.Calculate() be an interface over Fee. Without that, you have to rely on faith to say this:

    “The signature of the method is important. It accepts a Fee object, but returns the total directly. It doesn’t try to modify the Fee, allowing for a side-effect free function.”

    because there may be some future IBalanceCalculator which does modify the fee in its Calculate() method. Change the type to IImmutableFee and you have asserterd that no (present or future) implementation of this method will ever change the Fee passed in.

    The argument above about whether this is dynamic dispatch is perhaps rooted in the distinction between virtual and non-virtual method calls. Some people do not use “dispatch” when talking about non-virtual method calls, and therefore understand “double dispatch” as meaning a method call which depends on the runtime types of two objects. That’s certainly a difference between the context of the pages on the C2 wiki and this example here: the Fee object is concrete, so this setup is only dispatching on the type of the IBalanceCalculator.

    There is no doubt at all in my mind that if IBalanceCalculator.CalculateBalance() took an instance of an IImmutableFee interface that this is double dispatch.

    • chandida

      how does the IImmutableFee work? any links

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Dave

    That’s an interesting approach. It reminds me quite a bit of Udi’s concept of role-specific interfaces on entities. I’ll definitely keep that in mind!

  • Stu

    Hi,

    I have a problem that I’ve explained on Stack Overflow. Basically I have a situation where neither double dispatch or domain events seem to fit properly. Does anyone have any suggestions?

    http://stackoverflow.com/questions/3148853/service-behaviour-in-entity-how-to-avoid-service-injection-into-entity

  • Joseph

    This is not double dispatch. A single dispatch “pattern” selects a method depending on the name of the method and the type of the reciever (here, IBalanceCalculator). A double dispatch “pattern” selects a method depending on the name of the method and the type of two receivers. That is, the correct method is selected only after the executed has determined the correct dynamically bound method depending on the two receivers. In this example, we do not have a method selection based on two receivers, therefore, it is not a double dispatch.

    Moreover, double dispatch is not a pattern, but an implementation technique to realize various patterns such as the visitor pattern.

    I can highly recommend everybody to look at “Design Patterns – Elements of Reusable Object-Oriented Software”. Specifically, chapter 5, Visitor Pattern, pages 338-339.

  • http://www.heartysoft.com ashic

    Just arrived here from derick’s blog…and have to agree with Joseph. While reading the post I kept thinking “hang on, this is the visitor pattern”.

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Joseph, ashic

    You’re both wrong, it’s the double distrategisitor pattern! Anyway, this is the term used for this pattern on the DDD lists. If it’s confusing, apologies.

  • chandra

    i am not able to justify whether to use dependency injection or double dispatch, your blog says to use double dispatch but if you go in the below link http://danhaywood.com/2010/04/30/accessing-domain-services-from-entities/ you will find he is against double dispatching and stress on dependency injection which you are against of.

    On that blog it is wriitten that ,


    This design works well enough when the entity is called by the application layer; the application layer can easily access all the domain services, and so can pass in the appropriate service. If the entity is called by another entity then it’s more problematic, because the calling entity will in turn need to be passed in that entity, and transitively all the way back to the original call from the application layer.
    So I’m not keen on this design, because it in effect exposes implementation details to the caller ”

    Now who will you justify the above statement ?

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @chandra

    I find the design to be less-intention revealing that way. In his example, setter injection is used to supply the service. This leads to several design issues:

    - It’s possible to construct the object without the required services
    - It’s not clear which operations on the domain object use which services. The signature of the method does not expose which services are needed
    - If you use constructor injection, you’re now required to supply _all_ services for _all_ operations, even though you might be only using one operation at a time.

    That’s why I find double-dispatch to be the most intention-revealing interface – it’s part of the signature of the method of what exactly this operation requires to execute correctly.

  • Bhoomi

    Great post.

    “RecordPayment” is passed in IBalanceCalculator instance.
    Who creates IBalanceCalculator instance?

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Bhoomi

    Whoever calls this method is responsible for passing it in. Typically, it’s the container that builds this up, then a calling service that passes it in.

  • http://hammerproject.com/ matt kocaj

    Since we’re trying not to inject things into our model objects and we certainly don’t want them concerned with knowing what a Repository is, then is a service (domain service) the appropriate place to have a Repository injected for acquiring items from other aggregates if that’s the sort of logic that is required in some method of a domain object?