See more advice from other programmers here.
I founded the C Gazette in the 80s, was editor-in-chief of UNIX Review in the 90s, and a columnist for Software Development Times (SD Times) in the 00s. I co-authored the book Practical Algorithms for Programmers, for Addison-Wesley and wrote several other books on programming for Intel Press. I have coded all my adult life and been a longtime contributor to open source projects. I am currently the editor-in-chief of Dr. Dobb’s. He is @platpypusguy on Twitter.
Most Notable Achievement:
To the extent that my career has been successful, it’s been the result of accumulating small achievements. None of those achievements, however, whether taken individually or in their sum, can compare to the singular success of having married my wife. Of that I am most proud—and grateful.
Most Frequently Used Languages:
In terms of the programming experience, the single most transformative piece of advice came from Jeff Fredrick (then at Agitar, and later co-founder of the CitCon conference) who, years ago, pushed me to make unit tests a standard development practice. The amount of debugging time I’ve saved by writing unit tests is to me incalculable. (And that is without doing TDD.)
However, in terms of making my code better, the best advice I ever got was from an essay by Jeff Bay in a little-noted book called The ThoughtWorks Anthology, published in 2008—so it is advice that I received comparatively late in my career. Bay listed a series of tight strictures to impose on developers who programmed in OO languages as if they were writing procedural code. One stricture he advised, which is my topic here, is to keep classes to no more than 50-60 lines of code.
When you look at the innumerable techniques taught in all the various books and seminars on code, none of them mentions such a limit. But it’s a profoundly useful constraint. Because most developers have never heard it suggested, they can’t envision how it might be important or even worth struggling to adopt. These are the principal benefits I’ve found:
- Adherence to the Single Responsibility Principle (SRP). Every class does no more than one thing. The limit essentially guarantees only a single responsibility is undertaken in any class, and so it materially enhances maintainability and reusability.
- Testability. It’s much easier to write tests for a class with 60 LOCs than one with 200 or more. Because each class does only one thing, that one thing can be tested thoroughly. Since adopting this technique, my test code coverage has risen from roughly 55% to nearly 80%. Moreover, I have higher confidence in my code because within the covered code, it’s tested much more thoroughly.
- Readability. When you can see all that a class does on a single screen, it’s much easier to grok what is happening and so locate a defect. This aspect is even more evident in the debugger, where the window for displaying code is generally smaller.
An insistence on small classes also changes the way you think about code, in ways similar to how TDD enthusiasts talk about its way of rewiring synapses. As I break elements down into atomic-level components, I uncover small ways of optimizing the design. I see new ways in which I can reassemble the parts, and so the quality of the code improves. This is very hard to do if you regularly write 200+ line classes, because you’re never examining the code at a low level, but rather in big chunks that are like aggregate—the building material—in which sand, stones, and cement are all intermixed in one slurry that eventually hardens into stone.
Writing small classes also changes the structure of projects. Packages, which previously were somewhat arbitrary confederations of tangentially related classes, now become tight groupings of functionality. (For example, one package might contain a dozen or so classes used in command-line processing.) So, the tree of packages in a project gets considerably bushier. As a result, though, it becomes easier to navigate the codebase and find classes.
There are some challenges to writing code in this style. The biggest one initially is insisting on the limit when you just want to get ahead with the project and bang out the code. Invariably, though, the discipline pays off. You get really good at the refactoring techniques that can remove code (extract method, extract class, etc.).
The second major challenge is finding names for the larger number of classes. Sometimes it can be challenging to find the words to describe just one activity. I have many classes that end with Extractor, Converter, Renamer, Truncator, Extender, etc. The larger skill is to make the names meaningful enough that when you descend the package tree later on, the name remain meaningful. As a result, class names are longer than in standard coding approaches.
Finally, you need a good IDE. Because the classes are smaller, I have more of them open at one time. The IDE should be able to handle having many classes open and allow for easy navigation back and forth between them. It should have good refactoring capabilities to keep classes small as you cross the size threshold. I use JetBrains’ excellent IntelliJ IDEA in Java, although I’m sure other IDEs would work well too.
As a rule, programmers don’t cotton to artificial limits. However, those who are willing to try out this technique will find, as I did, that it’s one of the very few practices that delivers maintainability, testability, readability, and reusability. For me, at least, that’s been a worthwhile trade. (I discuss some of the techniques for keeping classes small here: http://www.drdobbs.com/230600127.)