Archive for the ‘Domain Driven Design’ tag
DDD: Bounded Contexts
I’ve been reading Casey Charlton’s excellent series of posts on Domain Driven Design recently and today came across his thoughts about which types of applications Domain Driven Design is suited to.
Towards the end of the post he talks about the fact that there is a lot of excellent ideas in Domain Driven Design even if you don’t have the chance to use all of them.
…there is a wealth of wisdom and experience encapsulated in Domain Driven Design – use what you think applies to your situation, and you will find your software becoming more flexible, more reactive to your audience, and easier to understand – just don’t expect miracles, and beware of over complicating your code for the sake of it – sometimes simpler really is better.
A pattern which I think is applicable in the majority of systems is bounded context – if I remember correctly this isn’t mentioned in InfoQ’s Domain Driven Quickly book but is extensively covered in the big blue book.
To quote the book with regards to what a bounded context is:
The delimited applicability of a particular model. BOUNDING CONTEXTS gives team members a clear and shared understanding of what has to be consistent and what can develop independently.
This means that a given model which we define is only valid in a specific part of our system. We would then have a layer of mapping between this bounded context and other parts of the system.
I’ve found this to be a really useful pattern to help reduce complexity where our application has integration end points. It makes it significantly easier to understand the code as you don’t need to keep all the context of what terms mean in other systems.
One thing that we discussed in our Domain Driven Design book club last week is that there are actually bounded contexts within the application itself as well as within the system as a whole.
For example if our application has a back-end database then that represents a relational model of the data in our system – that representation doesn’t make sense in other parts of the system and would typically be encapsulated from our code with the help of an ORM – the ORM effectively acting as an anti corruption layer between the database and our domain model.
I think we can also apply this with regards to the model we use on our user interfaces – often the model we display to our users differs from the one that makes sense to the business.
The only disadvantage of creating all these different bounded contexts is that we need to create mapping code between each of them, a job which can be pretty tedious at times.
On the other hand I think the advantages we get from having clearly defined areas where our various models are valid easily outweigh this in most cases.
Trade Offs: Some Thoughts
As we know with software development with pretty much every decision we make or technology we choose there is a trade off that goes with making this choice as compared with choosing an alternative.
I first learnt this when working with Ade a couple of years ago and while I know it to be true, I had come to believe that some practices are just non-negotiable and we should look to apply them judiciously wherever possible.
Various conversations have made me come to the realisation that not everyone believes this and that there are trade offs being made by following or not following these practices.
Domain Driven Design Ubiquitous Language
I consider this approach to writing software to be absolutely key to ensuring that the code base is easy to navigate around for newcomers and indeed to anyone who has to read the code after we have written it.
The trade off we are making here is that sometimes we will end up writing more code in designing our code around the language of the business rather than choosing a solution which may be technically easier to implement but less expressive.
To take a simple example of this in action, consider car insurance.
As a customer I would provide the insurer with details about my car, where I live and so on. This information would lead to me being provided with a Quote. Should I then decide to buy that Quote it would become a Policy. There is clearly quite an important difference between the two terms but in terms of data, maybe 75% is the same across both concepts.
If we decide to implement the language of the business in our code then we may end up creating a new object and copying a lot of data across from the old one.
The benefit we get from doing this is that the code is more expressive and describes the business process more accurately.
Interacting with other systems
My thoughts when it comes to using data from other systems is that we should look to keep interaction with the other system in one place – inside the anti corruption layer.
The benefit of doing this is that we keep control over our model and similar (but not exactly the same) concepts from other systems don’t creep into our application and lead to confusion around our domain model.
The disadvantage is that we may end up writing a lot of mapping code depending on how closely the other systems’ models are to our own. This code tends to be extremely tedious to write and difficult to test in a way that doesn’t involved re-creating most of the production code logic in our tests to create our expectations.
Object Oriented Programming
I have had the opportunity recently to work with several people who really know how to write code in this way and I’ve found it to be the most effective way to manage complexity in code that I’ve come across so far.
I’ve a long way to go before I’ve mastered OOP, but I try to follow the SOLID principles as much as possible – keeping classes small, behaviour with data and so on. – and I think it helps to make code much easier to understand and indeed change.
Now the trade off is that it is much harder to write code in this way than to just write procedural code and create anaemic objects which just have getters and setters on them. It also requires much more thinking – we have to think where to put behaviour, how to name new classes and so on.
Therefore I could easily see an argument that it’s quicker to write code procedurally than in an object oriented way. If we take this approach though we have to be prepared for the time we lose later on when it comes to trying to change the code that we were able to write so quickly before – it will probably take much longer now.
In Summary
I still believe that there is a lot of value in these approaches but it’s always good to know what alternative approach is being discarded by choosing a particular approach.
That way we can make more informed decisions.
How does the user language fit in with the ubiquitous language?
We’ve been doing some work this week around trying to ensure that we have a ubiquitous language to describe aspects of the domain across the various different systems on my project.
It’s not easy as there are several different teams involved but one thing we realised while working on the language is that the language of the business is not the same as the language of the user.
Although this is the first time that I recall working on a project where the language of the user is different to the language of the domain I’m sure there must be other domains where this is the case as well.
In our case the language is simplified so that it makes sense to the user – the terms used by the business make sense in that context but would be completely alien if we used it on the interfaces from which our users interact with the system.
At the moment our domain model represents the business terminology and then when we show the data to the user we refer to it by a different name. The problem with this approach is that there is a mental translation step in trying to remember which business term maps to which user term.
We can probably solve this problem somewhat by having the user terms represented in our Presentation Model but this still doesn’t help remove the translation problem when it comes to discussions away from the code.
At the moment there aren’t that many terms which differ but I’m not sure what the approach should be if there become more in the future, should we have a whole user language as well as a business specific ubiquitous one or should our ubiquitous language be the user language?