There is a finite amount of information we can keep in our heads at any given time. Over the years, software developers have created cheats to work around the limitations in our brains. One cheat is to turn problem solving into a massively parallel operation by collaborating with other humans. Another involves creating new, abstract concepts to represent chunks of knowledge. These tools—collaboration and abstraction—give us what we need to think through, analyze, and understand our architectures.
Abstractions help us focus on specific details at the expense of others. For example, an interface of a class in object-oriented programming describes the public methods but says nothing about how we should implement those methods. The concrete implementation of the interface provides those details. Removing these distracting details tightens focus on what you want to think about: the interface.
Of course, the perfect abstraction is not useful if we can’t share it. Anyone can draw boxes and lines. Creating a genuinely useful model of the architecture takes serious thought. A model, unlike any old sketch, is a precise and accurate description of some piece of the architecture that enhances communication and can be used to reason about the system.
Good architecture models have many benefits:
Words matter. A good element name will convey meaning and intent. Each model we create extends the software system’s vocabulary. We use this vocabulary in our day-to-day discussions, but it also permeates the code we write and shapes the way we see the world.
In software development, details are everything. Just because all details are important it does not mean we want to (or have the cognitive capacity to) think about all the details at the same time. Models let us hide some details so we can focus only on what is needed at this moment to answer a specific question.
Models make it easier to think about and describe how the system would behave. If we build the right models of our architecture, we can use them to test our designs before implementing the system too. We’ll still need to run experiments and build prototypes so that we can learn how to create accurate models. Even then, running an experiment is significantly cheaper and faster than learning that the design stinks after we built the whole system!
All developers should understand why we designed the system the way we did. Great models express the intent behind the structures. The more people who understand this intent, the greater the chance we’ll have of maintaining the system’s conceptual design integrity as we evolve the system over time.
Models are born from our perception of the world and our struggle to communicate the deeper meaning behind our design intent. Every model has concepts and rules, which describe how to use those concepts. Correctly applying the rules keeps the model consistent with our perception of the world.
Gregor Hohpe, author of Enterprise Integration Patterns: Designing and Deploying Messaging Solutions [HW04] and 37 Things and Architect Knows: A Chief Architect’s Journey [Hoh16], has a saying: A month of coding can save an hour of architecting. We know that architecture flaws are cheaper and faster to fix while we’re still designing architecture than when we’re writing code, running acceptance tests, or (gasp!) reviewing customer complaints after release. Gregor knows that an architecture problem is much faster to fix while it’s on a whiteboard than captured in thousands of lines of code.
Writing code is a fantastic way to learn about the system and how to design it. We should write code early. We should run experiments and build prototypes while we’re discovering the architecture. Thinking about models is not a substitute for firsthand experience. It is impossible to predict everything about a software system only with diagrams.
As you learned in Decide How Much to Design Up Front, we’ll end up with an architecture whether we design it up front, let it emerge as we write code, or do a little of both. Before you skip modeling the architecture and jump straight into writing code, think for a moment. When do you want to pay for your design and how much rework can you afford? A month of coding can save an hour of architecting.
18.216.244.98