I am a software engineer who worked on many systems ranging from small and simple to large and complex. I have had the opportunity to design, build, maintain, and support those systems. In my years of experience, I have realized that quality begins in the design phase. I attempt to summarize that experience and give you some tips, even checklists you can use in your next design task. The content is intended to be general. So, you need to adapt some of the steps to your specific use case.
Opinions expressed are solely my own and do not express the views or opinions of my employer.
All successful engineering projects begin with a well-defined problem statement. Each project is different. Often, there is a gap between what you think is needed and what is needed. Sometimes, a Product/Project Manager(PM) can articulate those requirements into a nice document. Other times, you will have to do it yourself. In any case, here are some helpful things to do.
We have a problem, a good one. You know where you want to go but don't yet know how. It's like you know you want to get to the Grand Canyon. You know you can reserve flights and rooms online. But you haven't found the cheapest prices for the experience you would love to have. There are a lot of moving parts.
You may have a lot of information on your hands or barely know anything at this point. That is normal. When I am in this situation, I do this
Now that you have all the fuzzy boxes you need. It is time to divide and conquer. You can divide the rough boxes into 3 categories.
These are the same as the clear boxes, except some basics are missing.
For brevity's sake, I will only talk about the clear boxes. I will go into more detail on the next two categories in the coming articles.
“If everything’s a priority, then nothing’s a priority.” - Frank Sonnenberg
You must have heard that numerous times. Think about the things that this product needs to do. Is it resource efficiency, low latency, high availability, or all of those things? Which of those comes first, which is second, and so on. This list of priorities is crucial to how you approach designing your product.
Now that you have the rough boxes and all the little squiggly connecting lines, it is time to dive deeper. In this step, you try or test different options for each rough box. You will need several things for each of those. The following is a list of the most common ones.
Specifications.
User documentation.
Contacts: If a component is from another team, you will need at least 1 point of contact. This is useful if you have questions while exploring the component.
A test rig
Chances are, whoever built the components you are using already has a test rig.
Beg or borrow so you don't have to reinvent the wheel.
If there is none, build a simple one yourself. Just don't go all in. Do just enough to test the basic functionality you need.
A list of known dependencies
It is a great idea to check for vulnerabilities.
A list of known vulnerabilities
The presence of vulnerabilities may influence your decision to use or not to use a library.
Notes, lots of them
If you are designing a large system, chances are, there are several little details. So, keep well-organized notes you can refer to later.
It is okay to collect the items from the list for one box at a time. The idea is to not get overwhelmed by the breadth of the system and work in small, easy-to-handle increments.
Now that you have the rough boxes and you've explored the options. By this time, you should have a pretty good idea of what everything does. Now is the time to grab a pen and paper again. This time, you look at your initial drawing and make a more detailed drawing. This drawing will give you a good picture of how everything works. Time for another checklist
List the following scenarios:
The design won't be perfect in the first iteration. There is no shame in going back to it and redoing some bits. Make sure you are weighing costs, risks, and benefits wisely. Lastly, estimate and put everything into whatever work tracker you use at your company.