cat posts/2020-01-21-clean-code-what-i-still-believe.md
Clean code, what I still believe
In 2006 I wrote a post here called Do not start with an Interface. I’d spent a couple of years putting an IThis in front of every This, because a book told me to program to an interface, and most of those interfaces only ever had one implementation. Reading it now, it’s a young programmer finding out the hard way that an abstraction is a guess about the future, and that his guesses were mostly wrong. I wish I could say I learned it once.
Dan Abramov’s Goodbye, Clean Code has been going around since the 11th, and it’s the same lesson told better. A colleague of his wrote the resize logic for shapes in a graphics editor, rectangles and ovals and so on, each with its own handles, and the code was repetitive. Dan stayed up late, rewrote it into a neat set of composable direction and shape functions, about half the size, checked it into master without talking to anyone and went to bed proud. The next morning his boss had a one-on-one with him and politely asked him to revert it. He did, and he says it took him years to see that the boss was right. His closing line is “Let clean code guide you. Then let it go.”
I’ve been on both sides of that one-on-one. I’ve been the person who “cleaned up” a teammate’s code overnight, and I’ve been the manager asking someone to put it back, and the second is harder than it sounds, because the refactored version usually looks better. It’s shorter. Nobody can point at a duplicated block in it. What you’re actually objecting to is invisible in the diff, it’s the next six months of changes that haven’t happened yet.
Sandi Metz put it most precisely in The Wrong Abstraction a few years ago: “duplication is far cheaper than the wrong abstraction”. Her description of how it goes wrong is the thing I’ve watched happen in every codebase I’ve worked on. Someone extracts the duplication into a shared function. Time passes. A new requirement almost fits, so the next person adds a parameter and an if. Then another. Two years later there’s a function called ProcessOrder with seven boolean arguments and nobody wants to touch it. We have one of those right now, in our billing code, and I signed off on more of it than I like to admit.
So what do I still believe, after twenty-something years of this?
I still believe in names. Of everything in Bob Martin’s Clean Code, choosing good names for things is the advice that has never once let me down, and I’ve never seen a codebase hurt by too much attention to naming. If I could only enforce one thing in code review it would be that, and it’s the line in my old competency matrix I’d defend hardest.
I still believe in small functions, mostly, with a big asterisk. A 400-line method is a problem. But I’ve also read C# that had been split into so many three-line private methods that following one request meant jumping through fifteen of them, each with a name like HandleInternal. That’s the same long method with its lines shuffled into different places. I’d take a 60-line function that reads top to bottom over that.
I’ve mostly stopped believing in DRY as a rule. Two pieces of code that look the same aren’t the same if they change for different reasons. The resize handles in Dan’s story are the perfect example, they look alike today, and the first time the product person asks for ovals to snap differently from rectangles, the shared version starts growing flags. My rule now is the old rule of three, which Fowler credits to Don Roberts in Refactoring: write it once, copy it the second time and wince, abstract it the third time, when you’ve seen enough cases to know what actually varies. I break it all the time, but it’s a better default than abstracting on the first repeat.
And I’ve completely stopped believing that clean code is about the code. Dan’s real point, and the part that stung a bit, is that his refactor was a trust problem before it was a design problem. He rewrote a colleague’s work without a conversation. Nothing in a style guide covers that, and it does more damage to a team than any duplicated block ever has. When someone on my team wants to restructure code another engineer just wrote, the bar now is that they talk to that person first, and most of the time the conversation turns up a reason the code looks the way it does.
I don’t think Clean Code the book deserves the pile-on it’s getting in some of the threads this week, by the way. I read it around 2009 and it made me a better programmer at a time when I needed rules. Rules are how you learn. The problem is people (me, in 2006) who never get to the stage after the rules, where you know why each one exists well enough to tell when it doesn’t apply. Most of the code in that billing module was written by people who’d clearly read the book.