DDD – A rookie’s unanswered questions

domain-driven-design

I’ve decided to use DDD in one of my pet projects to find out what the fuss is about! Let me start off by saying that this (DDD) is the way software SHOULD be written, I’ve seen some strange patterns and conventions but DDD is really the most natural way of writing code.

Interesting points that I noted started with DDD:

  • I can now dream about code without being reminded of constraints set upon us by databases
    Persisting data now takes the backseat when developing a complex system (This might come back to bite me)
  • I feel a lot closer to the business and business problem at hand
  • Discussions between you and the client is now done on their neutral ground
  • Discussions between developers are in line with the code
  • I learned to love refactoring (You better make peace with that right now)

Question 1: Is an entity allowed to make repository calls? For instance, if you need to validate that a certain field is unique in the system, should you write a domain service or can the entity make a call to the repo?

Question 2: What is the best practice for validating a new entity? Should you have a Validate() function, or can the validation be done in the constructor?

Your thoughts on this?

Best Answer

Yes, you can call repositories from within entities. But should you do it? Probably not, it often gives you more technical problems that it will benefit you, it also has the risk of making performance tuning very difficult (mostly because it invites bad design).

The validation example also does not seem to justify calling repositories from your entities. Also your example seems to imply that your object can exist in an invalid state, this should be avoided, your domain object should always be in a valid state.

Validation should already start at domain object creation time. If the creation logic is simple, you can keep this kind of logic in the objects constructor. But still the creation logic is kind of separate from the rest of the logic as it’s only needed during creation time and not during the rest of the lifecycle of an object. Thus when creation logic gets complex enough, like calling repositories, you should spinoff this separate concern to another object, a factory object.

You clarified that you use frontend technology that creates objects for you. In that case, I would say that those object are just application value objects that can be used for input to your object factories (or constructors for that matter). Application validation of the fields though, should probably stay separate from your domain though.

In general you should try to avoid giving domain objects setters for all properties. Instead you should provide domain actions on the object. Thus instead of having a method like: setOrderStatus(Order.PROCESSED) you should have a method processOrder(). This way each method will always result in a valid state (or else throw an exception). Note that I write in general, as for trivial fields that have no connection to domain logic and are just representing data, you can still use setters.

For simple data centric applications this kind of approach might give too much overhead though. But then again, that’s not where DDD is meant to be used.