This is the main point of this post: Simplicity is an important design goal that is often overlooked.
Simplicity as a design goal
- Humans have an extremely limited attention span.
- Humans have limitations in how much information we can see and consider simultaneously.
- Humans love to build immense, extravagant, complicated structures.
- Complexity hides flaws and increases the barrier to entry.
In designing an airplane, weight must be carefully considered with every design decision. If not, inevitably the result ends up much heavier than intended. This leads to a long string of suboptimal performance concessions and design adjustments often leading to an unimpressive final result. By analogy, simplicity (like weight) should be considered as part of every design decision when constructing software and hardware systems.
Simplicity of use vs. Simplicity of design
Simplicity in use can be much different than simplicity of design. Both of these are extremely important considerations. For this post I am focused on the importance of design simplicity.
More on why design simplicity is important in hardware/software systems.
- Bringing new developers up to speed. Commercial projects have developer turnover, open-source projects continually attract new contributors.
- Understanding the architecture in order to make wise changes (we want to avoid well intentioned changes that have unintentional consequences.)
- More difficult to hide bugs, easier to isolate/locate bugs.
- Easier to test/validate performance and robustness.
Complexity of the design vs. complexity of the task.
We’ve heard this before. Often the task itself has an inherent complexity and this establishes some minimum level of complexity in the solution. Complex tasks result in complex solutions. Still, it is worth the effort to fight the complexity battle at every decision point.
When making things simpler accidentally makes things harder.
Life is complex. Simplicity isn’t the only design goal. The challenge of engineering is to balance all of the complexities and trade-offs to design and build a (nearly) best solution for the original purpose. We often have to give ground on our favorite principles to balance all the other constraints.
Is Documentation the solution to the problem of complexity?
I argue the answer is no, or not as much as we’d like it to be. Remember, humans have tremendously short attention spans and limited ability to hold complicated abstract design models in our brain. Too much documentation can increase the complexity of a project and be counter productive.
Is Layering the solution?
I argue the answer is sometimes, but not always as much as we’d like it to be. A new abstraction layer creates a new thing for a developer to learn that is “invented here”. It is often different from anything seen before. Now we’ve added new api’s the new developer must learn and keep in mind in addition to the standard language or hardware api’s that are commonly known. We need to be very strategic and deliberate when creating abstraction layers. In essence, every new abstraction layer adds a new language to the project.
Everything in balance
The quickest way for a good person to become evil (or annoying?) is for them to over focus on one single truth. So in the end, let’s stay smart and keep everything balanced. But let’s include simplicity in the final equation.
P.S. I know I’ve written about simplicity before. I’d like to follow up this post with another post exploring a concrete example of UAS autopilot/flight controller design.