Agile and domain driven design (part 1): Digital Services
In the last mini-series of posts I sketched out how to use DDD to build an explicit rich domain library that models the business domain and enforces the invariants within a narrow scope of an aggregate of entities. Catching up with my friend we got into a discussion about how we get to the point were are ready to implement things. How big can the model be? How do we scale to many two pizza teams? How do user needs, business processes, and screens relate to the domain focused OO design? We ended up talking about microservices. So in this series of post I am going to sketch how a large scale agile digital transformation programme gets to the point of cutting DDD code. I will then get into how a large project comes to be a platform with a micro-services architecture.
If we take a quick scan at the sourcecode for the last blog series it starts very much at the “ready to code” phase of delivering a feature or set of features. It has a UML model which could have been drafted on a whiteboard in an agile work area, it has a list of business rules for contracts, so some analysis and design has already happened,. How? Lets take a step right back to how we might run an agile project with continuous improvement and continuous delivery.
The agile governance process at my current shop has a fixed set of project phases to deliver digital services. That is a very key concept; we don’t delivery code, or applications, we deliver services. The services are enabled by digital assets but are typically run by people for people. The code is an enabler not the objective. The objective is a good user outcome on an optimised customer journey through the service. The users are not just the external customers but also the internal users manning the support desks. Changing the “team world-view” to be outcomes-focused, not input-focused, is once again about making the paradigm shift to focusing on the problems you are trying to solve, not the solution you are putting in place to solve the problem. In my current shop we often say the phrase “where is the user in this?” whenever we get dragged back into the old bad habits of seeing the system as a collection of screens, or processes, or code.
We build digital services in a series of programme phases, using scrum or kanban or a-another, where funding is only to be released when you successfully passed an assessment at the end of each phase. The phases are discovery, alpha, private beta, public beta and live where we make continuous improvement. There is an aggressive focus on identifying what is the minimum viable service that can be given to users, getting that into private beta, getting it used, iterating upon it based on real end-user feedback, then opening it up to anyone as a public beta. When you exit public beta you then continuously deliver new functionality to expand the service to be complete.
There is a bit of a danger that folks treat the assessment stages as some sort of fixed water-scrum-fall cycle rather than treating the build as one continuous agile process. I argue that in agile you should be looking to do the same sorts of things across all sprints. In the earlier sprints you are doing a lot more elaboration and user research and in the final sprints you are doing a lot more incremental improvement to existing code. It is a sliding scale in-between. You might learn something new in beta that leads you back to more elaboration and user research. Its agile, innit.
During the discovery phase a lot of research is undertaken to establish who are the users that will be served by the proposed digital service. The identified users can be organised into sets of “personas” which are fictional characters that model prototypical users. By way of a quick example you might identify that you have both small business customers and but also very large enterprise customers. So you might capture that into two separate personas that have slightly different needs or demands of your digital service. You would look to build a service map that expresses the high level outline of what the service will do. This might be a large poster laid out in a grid. The different groups of personas are swim lanes, and along each swim lanes are cells that summaries key stories on the customer journeys through the service.
At the end of the discovery phase you are assessed that you have figured out who you are building the service for, that you have mapped out at a high level what the service should offer users, that that you have done enough research and thinking to start getting into the details. The next phase is alpha. Here are you are free to rapidly prototype, mockup screens that explore challenging user interactions, write experimental code, and to generally drill into areas that you need to de-risk. You might try to de-risk complex user interactions, or complex processes, or complex system integration points, or complex data migrations, whatever. There should be a strong focus on testing screens and processes with real end-users. There should be a large body of structured user research. There might also be business analysis to iterate upon process maps with internal stakeholders.
At the end of alpha you will be assessed that you have identified the key risks and have prototyped and spiked out solutions. At the end of this you need a clear idea of what you will be building as your minimum viable service throughout the following private beta phase. Private beta and public beta are pretty straightforward concepts. Iteratively build out the minimum viable service with a small set of friendly customers. Improve that based on feedback, then open it up to anyone, and keep on improving it. After public beta you have your viable service that is adding value which can then be continuously expand upon.
One contentious area in the shop is whether the alpha only makes “throw-away code”. A personal friend who has been a top flight programmer for three decades says that he never got around to learning how to write throw-away code; he is always too busy learning and practicing how to write high quality code. In an agile world any code might be thrown away at any point where you learn something new; so why not write and adapt high quality and flexible code from the very first sprint? So in alpha knock up some scaffolding to setup the scenarios so that you want to explore but write and iterate upon real code just focusing on the specific pinch-points in the domain model, and/or focusing on key user experience, and/or key business processes you are looking to de-risk. Then in the following build-out replace the scaffolding and expanding out the initial core code focusing on domain driven design. The code held up by scaffolding can be test driven, domain driven, production quality code, always-trying-to-write-better-code type of code.
In the next post we will imagine that we have just joined such a digital service team as a programmer as the programme is ramping up its private beta build out to see how we get into some domain driven design.