I contributed two chapters to Robert C. Martin’s best-selling book Clean Code: one named “Clean Classes,” and one chapter on emergent design. That doesn’t make me an authority on the definition of clean, but it does mean that at least one other person (Bob) agreed with my perspective on clean.
Actually, Bob edited my chapter on Clean Classes to put his stamp on it. That meant adding a few more ideas and bits of code. It also meant applying a different take on a few things, such as how methods should be organized within a file-based class declaration. In other words, Bob and I didn’t agree on everything.
We (Bob, the other Object Mentor authors of the book, and me) did have a general consensus on what “clean” meant, and it’s in line with most other folks who wrote books on (primarily OO) software design. There is consensus around core clean code concepts such as small classes and functions, intention-revealing names, eschewing comments in favor of code with higher clarity, and minimizing duplication. Clean Code promoted these concepts, which are considered good design because they result in systems considered easier to understand and maintain. (The book also promoted many stylistic preferences–things we could debate until the cows came home, and for which an efficiency/effectiveness winner is likely purely contextual.)
(Note that I’m not saying there aren’t a small number of authorities who counter these core concepts. Consensus does not imply unanimity.)
The challenge: Even if we knew that everything in Clean Code was the absolute, research-proven way to do things, it doesn’t mean that everyone can immediately function more effectively in code written this way. In fact, productivity can initially go down for a developer until they’ve made the paradigm shift–the light bulb moment when things make sense, what Satir called the “transforming idea.”
Some people prefer longer functions (perhaps because they read more easily top-to-bottom), some people are ok with obscure names (perhaps because they’ve grown comfortable with them over the years in their codebase), some people still insist on comments that redundantly summarize the code, and some people find copy-paste-alter easier than touching existing code to introduce delegation. These preferences may represent “good enough for my current context.” But all of these preferences are for designs that are less than ideal.
My primary job as a technical coach is to help developers build software in a more effective manner. That means helping them take their messy software and shape it into something better. The cleanup involves Clean Code concepts, but also concepts from simple design, refactoring, design patterns, SOLID, The Pragmatic Programmer, and many other places. In general, these concepts do not contradict each other. They sometimes complement each other, they often overlap each other, but perhaps they are best looked at different perspectives toward the same end goal.
We do not disagree on what good design is, although it is often a matter of balance (everything in software is a tradeoff). Yes, short, single-responsibility functions are ideal for many reasons, but we can debate how we count the number of reasons a function has to change. And per simple design rule #4 (minimizing the number of moving parts), some people think it’s possible to go too far when it comes to “short.” But at least we agree that shorter is better most of the time.
The problem with the phrase most of the time is that it leads to a relativist mentality, which in turn provides fodder for excuses. People are good at convincing themselves they need not change their habits once given an opening. The excuses then lead to (you guessed it) crappy code, which is everywhere, almost an accepted conclusion for most people. And they know it’s crappy! They grouse about it, they fear touching it, they avoid it, and they break things unwittingly when they don’t fear it enough.
Part of being an effective coach means not overwhelming people. I hand-hold developers for a short while, gradually introducing new concepts to ease the transition toward more effective code looks like. For example, we might live with longer methods for the time being, until how they are better able to navigate the ravioli design. Or I won’t make a sweeping pass to delete all the doc-comments (e.g. Javadoc) until they’ve personally felt how unnecessary they are.
But I also ensure that the message is clear: The code in its current form is costing all of us. We have defects, late-night support calls, headaches, frustrated testers, slower rate of delivery, risk of losing customers, risk of going out of business, angry management, and risk of losing our job partly as a result of the crappy code we helped build. I talk about how and why clean code can improve things.
Feathers (not Michael) may be ruffled at the truth, but the nice thing about ruffling stiff feathers gently is you get a little air under them, which feels kind of cool.
To summarize: Contextual reality impacts our ability to create and work in a clean codebase. Individual experiences, team composition, existing codebases, and other factors all impact our ability to be clean. And yes, various perspectives on how to talk about clean exist. But the definition of clean–at least for OO software development–has been settled for a while.
Clean code ideals are not contextual.