Software Architecture Rule of Thumb — Requirements!
This one is simple but so, so key. We as humans have a tendency to extrapolate from limited knowledge. Someone says “I need you to build a widget” and we say “OK, I know how to build widgets” and off we go.
This Dilbert comic says it all:
I know you’ve heard this before, but I can’t emphasize it enough — before you go off building a design and an architecture for a new feature, please please get your requirements straight.
When I am asked to work on a new problem, be it a simple story or a big new product line, or choosing a third-party tool, I always make sure to gather requirements first, write them down, and get them reviewed and approved by anyone who has a stake in this — product, the dev team, management, UX and so on.
I make sure this is nailed down before I spend any real time on architecture, design, tool choices and so on. This is to avoid wasting time or stress on details until we know what it is we’re actually doing.
I usually put the requirements as the first section in a high-level design doc, and leave the rest of the doc empty.
What, Not How
When you gather requirements, make them declarative not imperative. They should describe what needs to be built, not how to build it. This takes more discipline than you would think, especially when the person providing requirements has enough technical chops to be dangerous.
It is so easy to describe the problem in terms of a specific solution. The problem with this is it locks you into a particular perspective and prevents you from seeing alternatives that are easier to build or are more robust.
This is actually a key area where you need to learn to push back on product. If they are giving you requirements that are littered with technical details,take it back to them and work with them to describe what this looks like from the perspective of the user, and what tasks the user actually needs to accomplish.
Use Testable Acceptance Criteria
It’s great to start with user stories that help you understand the tasks that need to be accomplished and why these are important.
But wherever possible, before getting started on design, I like to express requirements in terms of acceptance criteria.
What this means is that the requirements are described in terms of an actual action you can take to verify that the system behaves as expected.
This gives you something you can turn directly into a test. I like to use the GIVEN/WHEN/THEN form of Behavior-Driven Development.
I like acceptance criteria because they are specific, detailed, and action-oriented. Acceptance criteria often drive lots of “what about” questions because they are so nice and specific.
The other awesome thing about acceptance criteria is you can then test your design by exercising it by the acceptance criteria. I usually do this in the design doc itself, working through a series of sequence diagrams or flow charts or plain text to prove to myself and others that the design as it stands should serve to meet the requirements.
You Can Use This All Over The Place
This principle comes up so often in many scenarios, not just in designing a new feature
For example, a few years ago a colleague came to me for help because he’d gotten a very bad performance review even though he thought he was doing what was needed. It became clear as we talked that the boss had one idea and he had a completely different one. I convinced him that he needed to “gather requirements” from his boss, and get specific acceptance criteria from him that they both agreed on.
Another form of this approach is in the corporate use of OKRs (objectives and key results). These express the business goals in specific, measurable ways, so that everyone is on the same page.
I have tried to use it in relationships as well — what exactly do you mean by “clean the garage” or “keep the kitchen clean” — with mixed results :)
It also works really well with kids, especially my son who has a very logical, literal mind.
All this reminds me of the story of the woman who asked her programmer husband to stop by the store and buy a loaf of bread, and if they have eggs, get a dozen. He came back with a twelve loaves of bread.
It’s all about clear requirements.