今日推荐英文原文：《Simplicity Over Complexity!》
推荐理由：webpack 作为应用打包器来说家喻户晓，它的插件也多如牛毛。这个项目同样也是一个 webpack 的插件，但是不同于其他插件，它最大的特点就是只会往你的命令行输出里加彩虹猫……对，真的只是加猫而已，它能做的就是让你表明自己对彩虹猫的信仰，以及向周围的人宣传猫猫的伟大之处。
今日推荐英文原文：《Simplicity Over Complexity!》作者：Ines Panker
Simplicity Over Complexity!
Or is it the other way around?Today, I came to two realizations, both of them surprising and both of them essential. During an innocuous debate about code review, I suddenly discovered that only a few basic ideas underlie all of my coding-related decisions. One of them is: Simple is better than complex. And about three seconds later, I realized that this is neither a well-known mantra nor one that can be quickly explained. It’s a conviction that you grow into. But without having to wait for a few years, how do I explain it to my teammate?
To me, “simplicity over complexity” is a pragmatic answer to questions of many flavors, a simple Occam’s razor. It gives me two benefits:
- It lets me separate a problem into the part that I need to solve now and the part I can postpone.
- It gives me confidence in my decision because it is backed up by so many other theorems, principles, rules, and guidelines.
So What Does “Simple Is Better Than Complex” Even Mean?This guideline wants you to gravitate towards simpler solutions. You are meant to ask yourself often: Could you simplify your code and still achieve the same result? Could you simplify the design and still achieve the same goal?
It can be small things like: Are you overusing powerful language structures? Do you benefit from using a try- except statement, or does a simple if statement fit into your flow better?
Or it can be larger things like: Should you really support 20 different scenarios, or can you achieve a comparable user experience by providing just the most common three?
This guideline coaxes you to be vigilant about complexity and to demand good reasons for increasing it.
How Complexity Influences a ProjectAt the beginning of a project, there is no code, no specs. The future (the things we will have to create) is daunting, but the past (the things we did create) is simple. We’ve created nothing so far, and that was very simple; anybody could have done it 🙃.
Now we need to create something. We can’t create everything at once; what should we start with?
If we trust the booming startup scene, the pragmatic way is to start with an MVP. MVP stands for minimum viable product, a product with just enough features that it is useful, that it successfully completes its main task. The goal at this stage is to keep the costs of developing the project low until we have proof that we are developing the right features.
The MVP principle is just different phrasing for “simple is better than complex.” The simplest solution that solves your problem should be used. Do not increase complexity (i.e., costs) until you have good reasons to.
A similar concept is present in the Pareto Principle, which is also called the 80/20 rule or the law of the vital few. The Pareto Principle states that for many events, roughly 80% of the effects come from 20% of the causes, i.e., 80% of bug reports are caused by 20% of bugs; 80% of the time, 20% of the features are used.
The Pareto Principle originated in statistics, in economics, but has been applied to a wide range of topics. It supports our Simplicity over Complexity concept very well. Why bother supporting every conceivable workflow for our software if 80% of our customers use just 20% of the possible workflows?
Thus, to determine which features to develop first, we must be picky. Everything we build, we will also have to support for some time. Everything we add to our software will have a cost of maintenance and will influence how and at what cost we can build other, completely unrelated, new things.
What Is a Good Reason to Increase Complexity?On paper, all of the above seems logical. But it is also very vague. There is nothing even resembling an actual definition of either complexity or simplicity, nothing we can use as a rule of thumb to judge which feature is worth a month of effort, which six months, which just a day. And this is where the fog commences and the bickering becomes intense.
The real reason developers and managers don’t care for this guideline is that we don’t agree on the meaning of “simple.”
If I’m at a meeting and our biggest customer convinces me they will leave our company if we don’t deliver X by the end of the quarter, then to me this will seem like an “our-company-is-on-the-line” insanely good reason to increase complexity.
If, however, I am a new developer on the project, and I can see the software all scarred from botched passed projects, I might also be convinced that if we do not act now and start paying for our past misjudgments, then this project is doomed either way.
So what do we do?
We plan ahead.
This situation might be unsolvable. The most efficient way to resolve it is to avoid it. We don’t want to be in the position where the complexity has grown so much that we are having difficulties maintaining this project.
As long as a project is simple, it is easy to add more people to it and, crucially, it is easy to remember all the scenarios we are covering.
The more complex a project is, the longer it takes for new people to help meaningfully. The project becomes more and more dependant on its original authors, the only ones who still know what complexity was added where and why. But the project also becomes more and more buggy because of forgotten features and flows. And as it becomes more buggy, it also uses flexibility. A significant number of bugs sooner or later become features. Users don’t know which functionalities were intended and which were not. They start relying on the broken functionality, and every change from here on is a broken promise.
Interestingly, teams sometimes use tests to alleviate this problem. Even if something was unintentional, as long as a test is asserting it, it will alarm us if we accidentally change the logic. But I would argue that this is a futile defense. Very few tests are properly read, understood, or maintained. Such tests are just like sending perpetual drunken border officers to the border. We see them, but we do not take them seriously.
Is Every Exception Evil?On the other hand, when we write our code, we want it to be used by real-life people in real-life problems. Now, show me one problem in nature that has a clean, easy solution with no exceptions! There are none. Life is complicated and so is code.
It is only in theoretical settings that we can “ignore the air-resistance in this physics formula.”
And Still, Simplicity Is BetterAnd still, we need to know what the ideal is. We need to know what we are striving for so that we will know when we bend away from it so that we might know why we’ve bent away from it.
There is no magic solution; there is no three-step guide. Whether a good balance was struck between simplicity and complexity only becomes evident later on. Once made, the decision is often unchangeable or expensive to change.
But if we plan to continue working on some project for at least a bit longer, we should think of our future selves, who will have to live with this decision.
Is this feature really good in the long run?