20 September 2017
How can Domain Driven Design help with large scale agile development?
Agile processes such as Scrum define a way of organising work, but they tend not to say a whole lot about how to go about doing it. System designs are expected to somehow emerge from teams so long as they follow the right behaviours and technical practices.
Agile tends to stress the importance of minimal viable product as the main goal of development. Although working software should be the central concern of any development, this does not mean that you can skip the design process. Douglas Martin made this clear in considering book design:
Questions about whether design is necessary or affordable are quite beside the point: design is inevitable. The alternative to good design is bad design, not no design at allDesign is an unavoidable part of software development. In trying to avoid taking a "big design up front" approach and find the quickest route to shipping workable software you are likely to wind up with bad design that inhibits your agility over the long term.
Good design does not emerge - it needs to be curated
There's nothing in agile to suggest that you should dispense with design, it just tends to favour a more evolutionary and iterative style.
The problem is that the task-orientated focus in agile can discourage investment in significant design thinking. Given the time and financial pressure that most projects are under, developers tend to concentrate on adding features rather than understanding and enhancing the design.
In this kind of environment developers can become overly concerned with technology detail without sufficient consideration of the data and behaviour they are implementing. The code and database become the centre of attention and focus of much of the debate. A chasm opens between the technology solution and the real-life processes that are implemented by the business.
In the absence of any unifying design, these pressures can give rise to all sorts of design smells. Processing logic is implemented in user interfaces, data persistence is mixed in with processing logic, databases get bogged down in slow, locking queries and services get coupled together. The software that emerges is difficult to maintain while the processes it implements tend to be very fragile.
Putting faith in regular refactoring as a means of eventually achieving an optimum design is not enough. It might clean up the code, but it doesn't help to introduce new concepts or align the system with the business processes it is supposed to implement.
The bottom line is that you model software whether you are prepared to admit it or not. If you have five different developers working on a system then you will end up with a blend of five different designs in one. Each will have their own view of the world and terminology to describe it.
Where Domain Driven Design can help
Given that design should be an iterative activity then it should be possible to incorporate a technique like Domain Driven Design (DDD) into agile development. DDD encourages an iterative process of collaboration to explore a model and develop a shared language between development teams and domain experts. This can pay dividends later on in terms of time saved in maintenance through coherent design.
There are two aspects of Domain Driven Design. Firstly, there is the strategic aspect where you identify what's important to the business, how to divide up the work and how best to integrate it. This involves identifying the subdomains that express self-contained areas of data and behaviour and the bounded contexts that implement these processes as physical systems. The subdomains represent an abstract ideal while the bounded contexts are the reality worked on by teams.
This creates a strategic foundation that helps to define what teams should work on. It describes the wider context, helps to understand how development should be divided up into service-based chunks, highlights integration points and helps to explain where legacy systems fit into the overall picture. It's particularly useful in a large development organisation that has numerous teams working on different aspects of the same domain.
The second aspect of DDD is the more tactical aspect that seeks to understand the detail within each bounded context. This is the more involved world of identifying aggregates along with values, entities, services, events and modules. It requires more of an investment of understanding by individual teams, but this is where you can gain the benefits of a genuine shared language and widely understood design.
Scaling Domain Driven Design
If this sounds a little onerous, bear in mind that you are not duty bound to slavishly follow the tenants of a single methodology to the letter. You can pick and choose the parts that work for you. It's also worth bearing in mind that there are some very practical reasons why Domain Driven Design can be difficult to apply across larger organisations.
Large, agile organisations tend to be decentralised, making it hard to gain traction for an abstract modelling technique. There is a large "explanation tax" in winning buy-in for a modelling technique to a large and diverse body of stakeholders. You really can see the eyes of some product managers start to glaze over when you start talking about aggregates and bounded contexts. It's not because they are disinterested in their domain, it's just that they often have trouble getting excited about a technically-led modelling technique.
Let's fact it - DDD is far from perfect. It suffers from some needlessly complex explanation which can make it seem impenetrable. You need to become accustomed to an unfamiliar set of techniques to be able to participate in modelling. This can create a gap in understanding where models are used to provide faux scientific justification for what is merely a bunch of subjective judgements about how software should work.
My own experience in large (20+ teams) agile environments is that it is easier to gain traction at first by focusing on the strategic concepts of domains, sub-domains and bounded contexts. This provides an accessible framework around which you can organise regular discussion with domain experts as well as identifying the core service boundaries that teams will implement. You can dive in deeper with the teams who are interested in using the technique.
There's a balance to be struck here. At the very least DDD can provide a useful framework for identifying services, which is pretty valuable in a large development shop. Beyond that it's up to the teams to decide how they should be implementing the detail of bounded contexts.