So, you’ve come up with a beautiful, elegant, solid software design. But to move forward you have to get it approved. And to get it approved, you have to communicate it to others. Because, unfortunately, having the idea in your mind is not enough to get it built as you envisioned it. Getting your design across effectively is not a simple task, and many software engineers are not skilled at it. But as most skills, your skill at writing design documents can be improved, I hope this post helps you on your way.
As we write a design document we should keep two main concerns in mind:
In my opinion these are the three objectives of a good design document:
Get buy-in for the high-level architecture from relevant stakeholders (engineering managers, technical leaders, engineers from other relevant groups).
Provide a blueprint for implementation.
Provide documentation (for historical reference, onboarding etc.)
But most importantly: A design document may include a summary of requirements, if appropriate – but it should not read as a wishlist. Someone reading a design document should get a clear idea of what you are planning to do.
Who will be reading the design document:
People who need to approve/provide feedback on the design.
People who need to do the work outlined in the document.
The author (you’re not going to remember why you did any of this in a couple of months).
In addition to their role, readers may have varying context on the design:
Internal readers who already know the background whose memory just needs to be refreshed.
External readers or newcomers who have no or close to no context and need a high level overview of what this document will cover.
When we write a design doc we need to keep the purpose and the different audiences in mind so we can write the right thing in the right place at the right level of detail.
Now that we know why we’re writing a design document and for who, let’s get into what it should include:
I usually start my posts with some personal anecdote explaining the background for what I’m writing and how I came up with the idea. I could probably do the same for this one, but the truth is that I’m writing it because I ❤️ permissions. I don’t exactly know why they hold such magic for me, but it is what it is, I get excited about permissions. User roles, checking who’s allowed to do what and when, and making sure it all works together is just the best kind of fun!
You might not share my excitement, and that’s OK, I guess, but permissions are one of the basic building blocks of almost any application. The permissions framework I’ll present here can start simple and evolve as you go, so you can be sure you are gonna need it and it’s definitely worth the small effort of setting it up from the get-go.
I was lucky to be in Dropbox’s headquarters when Kim Scott came to speak about her (then) new book “Radical Candor”. Dropbox was nice enough to hand out free copies (yay! free books!) so I actually ended up reading most of the book on the flight home.
Even though the book was written with managers in mind, I found myself referring back to it pretty often. Its insights proved quite useful in my daily work as a software engineer, especially in processes which require written or in person interaction with our co-workers. A little bit of Radical Candor can totally change how we do and react to code or design reviews, driving better results and higher satisfaction.
Radical Candor: Some Background
Before I share how you should use Radical Candor while creating software, it might be helpful to explain what Radical Candor is. I will try to keep this section as short as possible, since it’s just setting up the background for how to use Radical Candor in the context of software processes. If you’re already familiar with the framework you can just skip to the next section (titled Radical Code Review).
Radical Candor is about giving guidance that’s kind and clear, specific and sincere
Have you ever tried to design a complicated bit of software and ended up with a great big tangled mess? Designing software is hard and formal processes can be frustrating. Is there a better way to approach this task? Mind maps are a fun and intuitive way to brainstorm and organize your ideas on paper or a whiteboard. In this talk I show how to use mind maps to design software well, convert your thought process into an excellent technical spec, and break it down into workable tasks while leaving lots of room for agility and flexibility.
I’ve never really had much of an opinion about error handling. This may come as a shock to people who know me as quite opinionated (in a good way!), but yeah. If I was coming into an existing code base I just did whatever they did before, and if I was writing from scratch I just did whatever felt right to me at the time.
When I recently read the error handling section in Clean Code by Uncle Bob, that was the first time I gave the subject any thought at all. Sometime later I ran into a bug which was caused by some code failing silently, and I realized it might be time to think about it a bit more. I might not be able to change how errors are handled in the entire code base I’m working on, but at least I would be informed on what approaches exists and what the tradeoffs are, and, you know, have an opinion about the matter.
There is a traditional story that tells of a rabbi who comes upon a guy sitting next to a fork in the road. The rabbi asks the guy which way is best to get to the city, and the guy answers: That one is a short road which is long, and the other is a long road which is short. The rabbi chooses the short road, but soon arrives at a field full of thorns which he can’t get through, and must turn back and take the other road, which actually leads him to the city.
The moral of the story, other than wondering if this guy was the first troll in history, is that sometimes trying to take a short cut will end up being longer than just doing it the long way.