Domain Models, Dependencies And Fighting Anemia

For a long time now, I’ve been in the camp that says you shouldn’t have domain entities take dependencies… but at this point I’m having a hard time remembering why. I’m sure I could dig up my old notes and blog posts, but I don’t feel like doing that right now. Rather, I wanted to discuss a scenario that I run into a lot – and am currently facing – anemic domain models. The problem that I constantly run into is that I need to have access to a repository or some other functionality inside of my entities in order to get something done. If I decide to go down the path of not letting my entities have dependencies, then I end up pulling the logic that might belong in my entities out into a service class and my domain model becomes anemic – nothing more than simple data transfer objects with a few simple factory methods for the various collections and child objects on the entity.

Here’s the scenario that I’m running into right now…

I have a Container with a collection of Assets. The Container class has an AddAsset method which takes a number of arguments that are used to create an Asset and then adds the new Asset to the Container’s collection. When a Container is first created, it has no Assets in yet. When the first asset is added to the container, I need to look up that Asset’s Family and set the Container’s Family to that. From that point forward, all Assets that are added to the Container must be in the same Family. If you try to add an Asset to the Container and it is not in the same Family, you get an error saying you can’t do that.

Sounds pretty simple, right? Just grab the Family off the Asset and assign it to the Container… but here’s the catch: the Family is not a property on the Asset and it cannot be a property on the Asset. The Asset has various Classifications associated with it (which are properties on the Asset) and the determination of what Family the Asset belongs to is done with a lookup based on the Asset’s Classifications. The Family cannot be set as a property on the Asset because the Family can change at any point in time, based on the Classifications. Our customers maintain the Families based on Classifications, and they can change them Classification –> Family relationship whenever they want, and the change is immediately reflected on all Assets that are affected. We can’t cache the changes because there are millions of Assets in the system and the Families change on a regular basis. It would be too much work for the system to cache this and would cause other problems, anyways.

And it gets even more fun: There are multiple ways to add an Asset to a Container, from the system’s perspective. You can scan an Asset onto a Container (using a barcode scanner), or you can import Assets from another Container to create a new Container. In either case, the very first Asset added must set the Container’s Family.

Long story short: in order to add an Asset to my Container, my Asset class must have a reference to the Family look up service.

So… what do do? How would you approach this situation? What options, patterns, processes, and code examples do you find useful in situations like this?

The options that I can think of, off-hand, are:

  1. Go the anemic domain route and push all the logic of adding an Asset to a Container out of the Container, so that this lookup can occur
  2. Allow the Container entity to reference the Family lookup service so that I can encapsulate all the logic I need between my Container and Asset
  3. Use some kind of notification from within the Container to say “I need the Family for these Classifications”, so that the Container doesn’t have to know about the Family lookup service, but can be told what Family to use when it needs to know
  4. Forget OO design and principles entirely, and duplicate the code wherever I need it, violating “Tell, Don’t Ask”, creating a procedural system, and generally causing me to pull my hair out with maintenance issues and bug fighting

Option #1: I’m tired of this option. I’m tired of anemic models that don’t have anything but getters/setters and simple collection management. I don’t want to go down this path anymore.

Option #2: This goes against the things I was taught, but I’m seriously questioning why I was taught this. Is it such a horrible thing for an Entity to take in a dependency? Of course, this introduces some potential problems when we talk about using NHibernate to reconstitute our Entities from the database. Yes, I know newer versions of NH support dependencies and parameterized constructors. That’s great for the people who are using the newer version of NH. We’re not, and the upgrade path is terrible due to the size, complexity and age of this system.

Option #3: I’m not even sure how to go down this path without adding a dependency to the Entities, in the first place. Secondly – what patterns would be appropriate for this? A Domain Event is wrong because this isn’t an event, it’s a request for information that is external to the Entity. A Command is wrong because this isn’t a fire-and-forget situation. A request/reply scenario sounds like it would work because it is that… but there are a dozen or more ways to implement this concept. Any suggestions on how to approach this? Any insight as to whether or not this approach is even viable, or at least, under what circumstances it is?

Option #4: Ok, this really isn’t an option. I’ll gladly go the anemic model route before I go back to this style of coding. :)

I’m sure there are other options which is why I’m asking how you approach this. If you can, provide links to example source code that shows what you are talking about (please don’t paste code directly in the comments – it looks horrible and is difficult to read. Use Pastie or Github Gists or something like that, and provide a description with a link in the comments here).


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

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in Analysis and Design, C#, Design Patterns, Domain Driven Design, Principles and Patterns. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.lostechies.com/members/bogardj/default.aspx bogardj
  • http://www.lostechies.com/members/derick.bailey/default.aspx derick.bailey

    @jimmy – yeah, i decided to with a _strategy pattern_ *nudge nudge* :) like you show in that post, for now. this is one of the possible patterns for option #2 that I mentioned, above. If someone else shows me a better way, though (and I’m hoping…), I’ll likely change what I’m doing.

  • http://zvolkov.com zvolkov

    Option 2 my friend. And remember to keep up with frameworks next time.

  • http://www.proace.com/blog Josh Arnold

    I’ve ran into this sort of situations a few times. I’ve done it the double dispatch route (as Jimmy and you have already mentioned), I’ve gone the builder pattern route, and I’ve also added more of a “domain command” layer – more like domain operations.

    The builder pattern looked something like: http://gist.github.com/592388

    In this particular case, I certainly agree that removing this behavior out of the domain clearly moves it toward being anemic. The weirdest part is that you essentially have a post-operation condition that triggers an event…You could potentially send the Container in the event and have the handler do the lookup? Although that seems weird because I’m sure you wouldn’t want that property to have a public setter.

    I think the double dispatch might be your best friend on this one.

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

    zvolkov – what franeworks are you referring to?

    josh – how does that builder idea affect testability, since you are new’ing up the builder in that method? what happens when the builder had dependencies? or am i talking about scenarios where the builder doesn’t work so well?

  • http://craigcav.wordpress.com/ CraigCav

    Sometimes when I find these problems cropping up, problems where my design feels awkward and the normal patterns don’t help, I find there are often aspects to the model that I’m missing, or a relationship between components isn’t being modelled appropriately. Could this be the case here?

    Granted this sounds really wishy-washy, but it’s hard to give a more solid answer without a deeper understanding of the problem you’re solving.

    You mentioned that an asset’s family can change at any time; does also this change the family of the container, if it has already been added? Is the container purely a “store” of assets belonging to the same family, or is there more to it than this? Would it make sense for the container to encapsulate the classification of the asset i.e. the container is responsible for managing the Classification –> Family relationships, and can therefore determine for itself the family of an asset?

    I find that throwing patterns at a problem doesnt always help (although im not suggesting thats what you’re doing). It sounds this could be a case where a nice long chat with your domain expert might steer you in the right direction, and help your refine your domain model.

  • http://derekgreer.lostechies.com Derek Greer

    Glad to see you posting this question to the community as it’s been something I’ve been mulling over for a few months now. I think the Strategy pattern is wonderful when there’s actually a variable algorithm at play that the collaborating/calling object cares about, but it seems inappropriate otherwise. In those cases, it really does seem more appropriate to use DI in conjunction with factories for creating new instances of the entity without taking on its dependencies within the otherwise unconcerned calling object. A less appealing alternative is the Service Locator pattern. As distasteful as that my be, it seems cleaner than having the dependencies leak out into the calling objects.

  • Damien

    I’m confused (though this isn’t directly related to the area of discussion). What happens if two Assets belonging to the same container have different classifications, that currently map to the same family, but may later be changed to different families? Or would this situation not occur, or is it irrelevant once an asset is in a collection?

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

    I say inject them and stop worrying.

    The difficulties jimmy bogards post (http://www.lostechies.com/blogs/jimmy_bogard/archive/2010/04/14/injecting-services-into-entities.aspx
    ) on injecting into services can be mitigated with approaches like automocking autofac-style delegate factories.

    As for how to do it without NH support? Unfortunately the same way you have to do injection in other code entry points you don’t have control over – the dreaded service locator in the constructor. At least once you upgrade NH, you can remove the reference to the SL code and fix the compile errors – its that or double dispatch and end up with more code to change when you upgrade.

    PS The framework zvolkov is referring to keeping up with is probably NH if you’re stuck on an old version!

  • http://www.drrandom.org Casey

    I’ve recently been sipping the CQRS kool-aid as prescribed by Greg Young and Udi Dahan (http://cqrs.wordpress.com/), which has been an interesting journey. One of the concepts I’ve picked up is the idea of modeling state changes explicitly, making them part of you Ubiquitous Language, and first class citizens. So in this context my thought would be to model the change in state of the Asset explicitly using a Command. The command (say AddAssetToContainer) would contain the Asset and relevant information required to complete the operation (target Container if that is known, Family, whatever else). Handling the command could be done in a number of ways, but probably a Handler where T is AddAssetToContainer (or possibly an AssetCommandHandler class which handles all of the commands for Assets, however you want to do it). The handler retrieves the appropriate Container, and then an AddAsset() method on the container takes care of adding it properly.

    Now, in truth, with my current most favorite way of thinking would be to go all out with an event store and a read model. In this scenario what would happen would be the command would be handled, applied to the Aggregate Root (Container in this case) as an event, and then the event store would store the event. From there event handlers take care of updating my read model, and I’ve got an event stream that I can use to see what happened with my aggregate across it’s lifetime. There are lots of ways of doing things, and lots if discussions about which is “better”, but it’s generally agreed that the aggregate should be able to provide a collection of uncommitted events, and be able to apply a collection of events, so the state at any point in time can be replicated. Practically it is usually a good idea to include snapshots of aggregate state periodically as well, so that when your re-hydrating your aggregate you aren’t going through 5 years of events and taking an epoc. The other interesting side-effect of this is that your entities no longer need to expose their data publicly, which is strange for me.

    Ok, so that was a bit rambling, back to the point….If I have learned one thing recently that altered the way I work it is that dogmatism is dangerous. If you find yourself making a decision because “that’s the way your supposed to do it”, then you should re-evaluate. I’ve discovered that this extends into the “Best Practice” areas that I fought hard to make part of my normal way of doing things. Things like TDD, ORM, architectural layering, I’m questioning it all. It looks like your doing the same thing, which is good. If you can’t see any reason why you shouldn’t inject services into your domain objects, then do it. If your wrong, well then you have another angle when you are considering the same thing in the future. In the realm of choices that can be made about software, its really not going to make or break your success. It will either make your life easier or harder, or maybe even be a wash. In any case there is value.

  • http://nomad3k.livejournal.com Chris Kemp

    Well, it seems to me that the weakness in this system is that the laws that define a family need to be properly codified. It is all very well that the user is able to redefine a Family, but there should be strong processes defined around this. One obvious process is that you need to reassess your containers.

    I would look to say that your containers do not contain assets, but rather they contain classified assets. Then, the code that was calling your domain entities would need to have access to the service that classifies assets. Also, storing classified assets means you would be able to reclassify your assets following changes to the definitions of what constitutes a Family, and to do this you wouldn’t need to search through your entire system reclassifying everything.

  • amir

    please refer to this url http://pastie.org/1177190

    I’m using DCI approach

  • http://ralfw.blogspot.com Ralf Westphal

    I´d say DDD can come to the rescue here: Think of a container entity which is intelligent about what to do with assets. It has dependencies to look up and calculate all sorts of thinks when it´s ask to execute some command on its state.

    Because, yes, an entity has state. Lots of state and deeply nested, if you like.

    But the structure of this state is not visible to the outside of the entity. It truely encapsulates its state. However, you can ask the entity for an extract of its state and it will happily pass to you some kind of snapshot.

    The entity is smart, its state, though, is dumb.

    I find this a very neat separation of concerns. And this can easily be implemented. And it sports loose coupling because the state´s structure is pretty much just locally know within the entity.

    -Ralf

  • Fernando Zamora

    Have you considered the mediator pattern (chapter 10) as described in Design Patterns in C#
    By: Steven John Metsker

    Your problem sounds very simiilar. It sounds as if your trying to manage relationships – category to asset.

    Just a thought.

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

    All – thanks for the suggestions and comments, so far. It’s been great thinking through this with so many different ideas.

    … and it just got a little more interesting – if not a little bit easier to see what the right thing to do is. i now have a requirement to ignore the Family if the Container’s Usage is set to Maintenance. In other words, if the Container is being used for Maintenance, don’t both with all of the Family related rules and process, because it doesn’t matter.

    This makes the strategy pattern, commands, and other options that people have suggested even more useful. I need to do a little more research on this, but I may be switching from a strategy pattern to a command pattern to facilitate the new requirement.

    i’ll keep this thread updated, and may do a new post once i figure out exactly what i need and why.

  • http://richarddingwall.name Richard Dingwall

    Domain entities shouldn’t _hold_ references to services, but they can use temporary references i.e. pass the service in as parameter to the AddAsset() method.

  • http://lostechies.com/derekgreer Derek Greer

    @Casey I’d love to see an example of what this looks like in practice that’s based on Derick’s problem domain.

    @Richard The reason for the rule is what’s in question. What are the reasons you would set forth for this rule? Do you see any SoC issues caused by requiring the entity’s consumer to be coupled to the dependency? If so, how would you suggest solving this? If not, what is your justification?

  • Kim

    Hi Derick, so what’s your view on this now? Which solution would you choose now?

  • kghastie

    Derick, this is well framed problem statement, just specific and based in real-world usage enough to be more than an abstract, conceptual discussion, but general enough to be understood by anyone. But you don’t say specifically what issues you’ve specifically run into with an anemic domain model. If the worst you can say is you are tired of working that way, I’m not sure you need an alternative…?

  • didibus

    I’m a bit confused by your example. You are saying that Families can not be a property of an asset, because they are inferred based on the classifications of the asset. This is why you have a Family Service which finds the Family of an Asset based on it’s classifications. But why can’t this logic be on the asset itself?

    You say the customer can change the logic of classifications -> family, this complicates it a bit.

    I would make a domain object called Family that stores a set of classifications. The user can change what classification define a family, when he does, I would change the Family object to reflect those changes.

    Then, on the Asset class, I would have a Family setFamily(List) method that match the Asset and returns the Family in a list of Families and also assign a reference to it on the Asset.

    Now I’d change container.addAsset to take a list of family also. Container.addAsset(Asset, List). It would add the Asset to itself, and it would call setFamily on the asset, passing it the current list of families. The Container would remember it’s firstAsset, so on the next call of addAsset, it would first call setFamily on the firstAsset, it would also call setFamily on the new Asset, and it would compare if the new Asset is of the same Family as the firstAsset, if it is, it would add that asset, if not, it would throw an exception.

    This way, you keep all the domain logic in the domain and you don’t have an anemic domain model.

    • didibus

      It’s also possible your Family lookup logic is not domain logic, but application logic. In that case, it’s totally fine to have your service implement the logic. All other domain logic you have can still go in your domain objects. If this logic is the only logic your application has, then your domain model is not anemic, it simply has no need for any domain behaviour. Eventually, you might have some need for it, like validation or other things. Though I think my above answer is better, because this does sound like domain logic in a way.