I'm a huge fan of simple things. But very few things start off being simple; we make them simple through effort. Consider that two hundred years ago, only the best and the brightest minds in the world had any understanding at all of electricity. It was less than 150 years ago that a few geniuses figured out how to make the first electric motors. Today, most sixth-grade science classes learn how electric motors work and they're ubiquitous in our society. That's only possible because people have taken a lot of time studying, considering, ruling out, re-thinking, re-framing, experimenting, and refining the ideas to the point where the principles have become simple and understandable and can be used as building blocks for more complex things. If the electric motor hadn't become so well understood and simplified, building things like copiers, cars, and power tools would still be gargantuan feats.
I've been thinking a lot about simplicity since we had a rush of clients coming to us for help with struggling projects recently. In every case, the major contributor to the problems they were facing was a lack of simplicity. In most cases, I was awed by the level of detail and technical wizardry I was looking at, and at the very same time, awed by how completely they had missed the point. Like those early electric motors, they were a wonder; something to marvel at. And yet those early motors were horrible, touchy, dangerous, and under-powered. Looking at this code, I thought, “Sure, it works, but will the next developer who works on it have to spend several days just to get his head around it (like I just did)? Will we be able to leverage it in the future? Does it perform well?” As is often the case, after stepping back and looking at the situations and thinking through them, simpler answers started to emerge. Most of the work involved tearing out huge, intricate pieces of code and replacing them with smaller, simpler bits. Sometimes the beauty of being a contractor is in your outside perspective: your ability to see the forest for the trees. But how do companies get so lost in the trees?
As a manager, I believe that if you can't explain something with a few sentences of plain English, you're not prepared to work on it. You need to think about it some more and re-work the problem. Before coding begins, make sure your developers can explain clearly and without using technical jargon, what they are setting out to accomplish and how they plan to go about it. You might be shocked at how often they can't. I've encountered developers who've been working on a task for days and yet can't explain to me what they're doing, or they have huge holes in their stories. It's our job as managers to keep this from happening and get things back on track if it does happen. We're in a unique position to see the bigger picture and provide a different perspective to help create clarity. During code reviews and progress reviews, there needs to be that same level of clarity. If you start to see things going down a rabbit hole or descriptions becoming convoluted or anyone getting lost, that's a big red flag. Stop and take a step back. Zoom out to the bigger picture. Understand what it is that needs to be accomplished and look at the steps being taken to get there. If you don't, you may work out the details, but at what cost?
My personal mantra when I write code is, “Make it work. Make it bullet-proof. Make it pretty.” I often take shortcuts to get something working, and then go back and clean up, pull out hard-coded values, change names to something that makes more sense, make sure I'm handling exceptions, etc. There's little I hate more than when someone breaks my code. It's a matter of pride. Once I'm pretty sure it's bullet-proof, I work on the “nice to have” features. That's usually where the details lie, but more importantly, this is the part where I look for places I can simplify. The next worst thing after someone breaking my code is someone not being able to follow my code. It should be clear as day, but not to me, to them. I once had a writing professor who passed on the idea that your writing wasn't done until you removed everything you could without compromising the story. “Simplify,” he said. I can usually eliminate a surprising amount of code before I consider the work done.
In some ways, we've shot ourselves in the foot when it comes to simplicity. There is an almost maniacal obsession about not repeating code and adding levels of indirection and abstraction. Those are good concepts and came into our industry for a reason, but we've taken them to an extreme. Fight the urge to trade simplicity and clarity for indirection and abstraction at every turn, and weigh the benefits with the costs. Sometimes simple is better, faster, and easier to understand. It's those pieces of code, the simplified ones, that become the building blocks for the next level of development and not the Rube-Goldberg code that dices, slices, chops, and purees, but not very well and only if you can figure out how to work it.
It's up to the managers to show developers how to find the clarity and simplicity to create better products. Force the issue by making sure everyone can clearly state the objectives and how they will be accomplished. Discuss if there is a better way to accomplish objectives. Do all of this before any code is written, then do it again, and again, and again throughout the project. Remember, whenever someone says, “It's complicated,” it almost never is. What they mean is, “I don't understand it and/or don't want to own up to it.”