Twenty years ago, an agile rebellion started among a small pocket of besieged software developers. Today, the benefits of agile methodologies have improved stock trading, federal bureaucracies, and celebrity chef-led humanitarian efforts. Yet Agile has started to lose favor. This has prompted us to get back tobasics and start a series focusing on the Principles of Agile.
The tenth Principle of the Agile Manifesto reads:
Simplicity – the art of maximizing the amount of work not done – is essential.
It shouldn’t surprise you that striving for simplicity is kind of a big focus around here at, uh, Simple Thread. We often write about managing complexity in design, simplifying the development process, accidental versus essential complexity, ways to compress complexity, and so on.
I’m always happy to revisit that timeless struggle of managing complexity, but instead I want to focus on the definition of simplicity mentioned in the principle: the art of maximizing the amount of work not done.
That almost has the feeling of a Zen koan, paradoxical but profound. I should do more of doing less? Yes, exactly.
True at every scale
What I love about this framing of simplicity is how it is true at every scale of thinking about software development. It’s true when thinking about class design or system architecture. It’s true when thinking of product design. It’s even true thinking about organizational management.
The code you write makes you a programmer. The code you delete makes you a good one. The code you don’t have to write makes you a great one.
It’s true even at the very small detail of fixing a bug. When you get a bug reported and find the offending logic, your first instinct is typically to add some code to prevent it from happening again, e.g., some guard clauses. That may be the right solution, but it’s remarkable how often you can fix the problem by deleting unnecessary code that had a bad assumption. Subtractive thinking often solves problems more cleanly.
One of my most productive days was throwing away 1000 lines of code.
Ken Thompson, creator of Unix
If you take a step higher and think about designing new functionality, most problems come from trying to have a class do too much, having components handle too many scenarios, and trying to predict the future. Keep responsibility focused and avoid handling conditions until you need to. Chances are, YAGNI. There’s a reason why most senior engineers follow the rule of three, waiting to create abstractions until similar code exists in three places. Don’t do that extra work until you need to.
Duplication is far cheaper than the wrong abstraction.
If you zoom out further and think about system architecture, simplicity becomes even more critical, because you have more pieces interacting, more combinations of behavior to explode complexity.
At Simple Thread, we always push to build small vertical slices of our systems as soon as practical, instead of building broad horizontal layers with no visibility to business stakeholders. This lets us collaborate, validate, and get feedback from users more quickly. It helps us avoid feature rework and building large pieces of infrastructure that we will never actually need.
It’s a bit heartbreaking when I hear about engineering teams at startups spending months getting their kubernetes clusters working to support their elaborate microservices architecture. It’s ostensibly so they’ll be ready when they need to scale – you know, if their unvalidated idea actually gets traction. But usually, that’s all work that should be avoided, for now. Build the MVP, get customer feedback, and iterate. A monolith can actually get you very far.
Product Strategy is about Saying No
Let’s move up another level to think about the software product as a whole.
One of my favorite short talks on product strategy is Product Strategy is about Saying No by Des Traynor at 2013 Business of Software. He discusses how business pressures can make it so, so easy to say yes, and why it’s so, so important to say no and stay focused on the product vision. Just watch the video; it’s only 7 minutes.
There are a couple of lessons that people sometimes just have to learn the hard way. When I’m working with product owners and even a lot of client product managers, they often don’t understand that the effort spent writing code is only a small fraction of the total cost of ownership.
Every line of code is an asset and a liability. It may provide value, but you need to maintain, test, patch, upgrade. It’s another line somebody has to read and understand when troubleshooting. Alone, a single line of code is rarely a problem, but collectively every line of code adds tremendous weight on the engineering team. It better be worth it.
Zooming out again, every feature is an asset and a liability.
Even if the code comprising it were free to develop and free to maintain, a feature has an inherent cost. It might have helped you win a big client, but now you have to include it in every platform and every new version – or risk alienating those customers. You have to factor in how this legacy feature will interact with every new feature in the roadmap. A single feature is rarely a huge problem, but collectively features become a weight that will make your system slow to adapt and untenable to maintain. It better be worth it.
It’s easy to say no to bad ideas. The problem is that if you have a good team, people will come to you with really great ideas – ideas that you absolutely want to say yes to.
Everything has a cost.
There’s a famous quote from Steve Jobs, which implies this idea holds true even at the scale of running a multinational company.
People think focus means saying yes to the thing you’ve got to focus on. But that’s not what it means at all. It means saying no to the hundred other good ideas that there are. You have to pick carefully. I’m actually as proud of the things we haven’t done as the things I have done. Innovation is saying ‘no’ to 1,000 things.
For most of us, our time and attention are limited, precious resources. When you say yes to one idea, you are saying no to something else. There is always a cost. Simplicity is often the price you pay when you say yes.
Simplicity doesn’t just happen. It’s the result of saying no, even when you want to say yes. It’s the result of deferring work and critical decisions until the last responsible moment. It’s the result of maximizing the work we’re not doing, not yet at least.
Simplicity might not feel as obviously connected to the core manifesto at first. But if you value delivering working software regularly and you value responding to change quickly, a vigilant dedication to simplicity is the only way to stay flexible and adaptable. A ruthless focus on simplicity is the only way to stay Agile.
Loved the article? Hated it? Didn’t even read it?
We’d love to hear from you.