So now you had an introduction to DDD you’ve probably gotten enthusiastic and started right away, of course! And then you ran into a couple of problems. As mentioned, your domain model must (always) be in a valid state. However, for some reason you were not able to.
Let’s for example, create a domain model for an appointment:
Pretty straight forward right? There’s a nice couple of properties, and a constructor accepting a title, start- and end date.
Now the problem here is that as soon as the domain model is instantiated, it may be invalid. This is because an appointment has a start- and end date on which validation rules apply. But in this situation, there’s no way I can validate the start and end date. You can validate the start- and end date in the constructor, because both the start and the end date are passed to the constructor. The problem is, when editing the appointment.
The user made a mistake entering the appointment and needs to change the start- and end date of the appointment. When you fetch the domain model from a data store and start changing the dates, there’s no way to verify if a value is valid or not. If you pass the start date, it’s validated against an old end date and vice versa. In this situation, you want to use value objects.
Let’s refactor the above domain model so it holds a value object with which we can make sure the domain model is always valid. First, we create a value object called DateRange. Take a peek at the following code :
The DateRange object holds a Start- and an End date for a date range. The Appointment Domain Model is changed, so it holds a DateRange object property named Schedule. Now if a user wants the change the appointment, you create a new DateRange object containing the start- and the end date and pass it to the SetSchedule method. This method accepts the DateRange object and validates if the start date is actually earlier than the end date. And now everybody is happy, and our domain model is always valid.