Let’s talk Domain Driven Design
Key take-aways from DDD eXchange 2017
By Petya Afanasiev
Domain Driven Design, or DDD, is a methodology or an approach in software development that emphasises the importance of getting your ‘Domain’ or business logic right. The term was coined by Eric Evans in his book ‘Domain-Driven Design: Tackling Complexity in the Heart of Software’.
At Skyscanner, we have a good tradition of visiting the most interesting conferences and I was lucky enough to attend the DDDx Conf in London this April. DDDx is probably one of the main DDD events there is, with Eric Evans himself delivering a keynote every year since this conference began nine years ago.
This year the focus was far less on the technical details of properly implementing DDD in your application (things like Value Objects, Aggregates, Domain Events, etc.) but more on the three most difficult parts:
Crunching the domain, talking to people and learning!
Many great speakers presented their thoughts. Here are my notes on the two that struck and inspired me the most.
Eric Evans — Good Design is Imperfect Design
DDD eXchange 2017 conference cast. Eric Evans: DDD is often invoked to justify perfectionism, or sometimes it sets up…skillsmatter.com
Eric delivered a great talk exploring every developer’s need to strive for perfection. This is especially true for someone who practices DDD. Domain modelling is very hard to get right and if some assumptions were incorrect, a small change in business processes might suddenly render the entire model inefficient. And here lies the caveat — how do you live with an imperfect model? Can DDD even be used in this case? Or should you strive to always find the perfect model and constantly refactor towards it?
Eric argued that having a perfect model is, of course, preferable but practically unreachable. So a good developer should learn how to work with imperfection and suggested a few useful tricks.
A well known and loved tool in a DDD practitioner’s toolbelt. Bounded contexts are isolated zones where all terms, entities and events have a certain specific definition. The same terms might have a slightly different meaning outside of this context and the same processes and rules might be interpreted slightly differently elsewhere. Bounded contexts could be used to isolate the part of your model that you think you got just right from the parts you’re still not sure about.
These go hand in hand with bounded contexts although an anti-corruption layer is really only necessary if your service interacts with a 3rd party or someone who doesn’t really care about your integration too much. This layer translates concepts into your domains language and fixes inconsistencies in the model or process if there are any. This way your perfect abstractions can remain isolated.
A common practice is to build a microservice around a bounded context — with the microservice’s API doing the anti-corruption part if necessary. But what if you can’t figure out an abstraction that fits 100% of your cases inside your own microservice? In this case, it’s usually better not to sacrifice your design that solves elegantly 95% of the cases to solve the remaining 5% but instead create an explicit Spill zone. This could be a class or a method that is very obviously named as ‘CasesWeHaventFiguredOut’ and where no abstraction is allowed. Only simple if-then-else conditional logic.
In general, when dealing with imperfection these are the guidelines one must keep in mind:
- Awkward names for awkward concepts.
Don’t try to hide inconsistencies or awkward design — make it explicit so that everyone who needs to work with it understands that this is something that could be improved or at least handled with care.
2. Differentiate messiness of neglect vs messiness of creativity
Creativity is a messy process that requires freedom of experimentation and mistakes. However, it is important to separate it from messiness occurring due to simple neglect or laziness. Otherwise, it will spill over to parts of your code that could have remained clean and solid.
3. DRY is for one Bounded Context
Most of the time duplicated code has a bad smell but it’s almost always a bad idea to refactor to create common abstractions across different bounded contexts. Different contexts tackle slightly different concepts and so inevitably will need to have different logic in the future which will hardly fit into a unified model.
And as a final piece of advice — we, as software developers need to learn to broaden our aesthetic. Software doesn’t need to be perfect.
Jenny Martin — Collaboration Driven Development outside in - peeling away the layers
DDD eXchange 2017 conference cast. Jenny Martin: According to various unsubstantiated historical reports, 20 years ago…skillsmatter.com
Jenny’s talk felt almost like a workshop. We collaborated a lot in smaller groups and discussed the main topic independently. The problem we tried to tackle was this:
‘How do you approach complex technical problems in an iterative way?’
She didn’t have a clear answer for us but the discussions did spark some interesting ideas:
It’s important to get the whole team aligned to the technical vision as early as possible, otherwise the design will be inconsistent. It’s also important to postpone the decisions as much as possible because the further down the timeline, the more informed every decision is. The balance between these two can be quite difficult to achieve but we came up with at least some guidelines:
- Whenever you start working on a new thing, be it the whole business, a project, a major release, an iteration or just a feature, the start of every such new ‘layer’ requires some time to design the foundations it. For example, in the beginning of a new project, it’s useful to set up the overall design for that project without going into too much detail for every component. But when starting a new iteration — it’s a good time to review the design of components involved in that iteration. And so on, the start of every new layer requires different level of design granularity.
- The balance will be different for different types of projects. So ‘pioneers’ who innovate and build something that has never been built before will need to be iterative and not delve too deep. The ‘city builders’ who are industrialising their process will need to make a lot of decisions early on.
Jenny then proceeded to present her Collaboration Driven Development concept:
Suddenly it is very clear that we already have great tools to assist us in upfront work for every layer in Analysis (Product design) and Testing but not so much in Technical Design. Perhaps Jenny will have this one figured out next year.
The conference was both thought-provoking and provided great inspiration. Apart from the two talks I covered in detail, I was also impressed with the talks of Alberto Brandolini, where he explored the deficiencies of modern agile processes, and Pete Buckney, who showcased the intricate details of creativity. But I would really encourage all engineers to watch any of the talks.
Domain Driven Design is such a beautiful concept that leaving the conference I couldn’t stop wondering, why is it still not mainstream after all these years? Is it because not that many people have the problem that it is meant to solve? Perhaps too many developers think: “my domain is not that complex, I can get away with something simpler”. To me, DDD doesn’t have to be complex and to use every single item from its toolbox definitely isn’t a requirement. The greatest benefits I see come from DDD’s core philosophy. It’s the value of understanding your domain precisely and being able to talk about it with different levels of stakeholders. And that is essential for anyone who aspires to be a good architect.
See you all next year!
Our team has a great mix of people with different interests and specialisms — we’ve got a few roles available so why not take a look?
At time of publishing these Job roles were Live, if they are no longer active do check out the other Skyscanner Engineering, Design and Marketing job roles.
Hear more updates about our vacancies and get more stories from us right to your inbox by signing up for our Skyscanner Engineering newsletter waiting list!
About the author
My name is Petya Afanasiev and I am currently a Senior Software Developer at Skyscanner. I started my career in software development in 2007 in Ukraine and later moved to work in Malta and just recently to London to join Skyscanner. I find it engaging to work at Skyscanner because I feel we are at the forefront, being a leader and innovator rather than a follower. And that is true for both our business and technical organizations.