When we design systems from scratch, especially complex distributed systems, we tend to make far reaching decisions at a very early stage - at a time, when we have the least knowledge about the underlying business problem. But some issues are impossible to solve just by assumption, and even with great experience, it’s quite common to get the first design at least partially wrong.
Unfortunately, the first design is also often the one that ends up being implemented.
On a technical level, this has immediate consequences: If we assume boundaries in the wrong place, or forget or omit important aspects of communication, we can end up with brittle services, performance issues, and needlessly coupled modules and components, which are painful to maintain and deploy.
On an organizational level, misplaced boundaries and unfortunate design decisions often lead to entire team structures and workflows in all the wrong places, thus creating immense communication overhead, or worse: active prevention of learning and improvement for the rest of the project lifetime.
One way to mitigate the impact of those decisions, and to verify our initial assumptions, is to start implementation not with a complete solution architecture in mind, but rather with the smallest possible footprint: A plain, but fully operational prototype of the domain model, which we can stress, observe and explore - and change easily, if we run into problems. This way, we can actually see our design work, and gain valuable insights.
As a side-effect, we can also deliver customer value much earlier, by using the raw domain model to power UX/UI prototypes - replacing fakes and click-dummies with a working application.
As a team, we can learn and improve together, making important decisions when they are needed, adding layer by layer of additional (technical) complexity in small, incremental steps, until we are truly ready to scale out.
We will play through a full development cycle of a (fictitious) business application to explore how combining UX prototyping, Domain Driven Design, and the practices, heuristics and principles of Software Crafting can highlight difficult or problematic choices, improve fundamental architecture decisions, and ultimately lead not only to better solutions, but also to a better and more sustainable software development process.
tba