At last week’s Austin DDD Book Club, we discussed my favorite chapter in Evans’ Domain-Driven Design book: Supple Design. Modeling is an important exercise in Domain-Driven Design, but it’s not enough to have a codebase that’s easy to work with. In addition to designs that are easily changed, supple designs enable changes originating from deep modeling.
Code can be easy to change technically with low coupling, high cohesion and a safety net of unit tests. But what about additions or new concepts to your model? With supple design, changes in the model are easily realized in your code. I’ve been involved in many projects where the conceptual model was clear and well-documented, but the design represented as code was a mess. There’s always a simplification going from model to code, but it shouldn’t be a translation.
Evans notes that developers have two roles that must be served by the design:
- Developer of a client, where concepts of the model are easily discerned and naturally composed
- Developer working to change it, so that changes necessary are visible and obvious
To move achieve a supple design, Evans lays out a set of design patterns:
- Intention-Revealing Interfaces
- Side-Effect-Free Functions
- Conceptual Contours
- Standalone Classes
- Closure of Operations
- Declarative Style of Design
The idea of a supple design is fairly abstract and hard to nail down. But its basic principles are those that go beyond simply code that is easy to change. If the code doesn’t reflect your actual model, it can be just as difficult to work with as bad code. With supple design, a model is more easily realized in code, eliminating some of the wasteful translations that happen on so many projects.
Over the next couple of weeks, I’ll dive in to each of the design patterns above. These design patterns aren’t structural, like Strategy or Visitor, but related to the model aspects of the design. By applying the concepts in the supple design patterns, we’ll have a codebase that’s both easy to change and a pleasure to work with.