One of the books I’m currently reading is Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin. It’s an excellent book and I highly recommend reading it to any software developer.
As you may have guessed, I’m currently on chapter twelve and I’m moving slowly through the book in order to absorb the information more thoroughly. There are plenty of passages in the book that merit quoting, but I wanted to highlight a machine-gunning of excellence I found in chapter twelve:
Most of us have had the experience of working on convoluted code. Many of us have produced some convoluted code ourselves. It’s easy to write code that we understand, because at the time we write it we’re deep in an understanding of the problem we’re trying to solve. Other maintainers of the code aren’t going to have so deep an understanding.
This, I think, is the heart of problems that creep up in a long-term project. When we’re trying to get something done — especially under the gun — it’s easy to rush things. This problem has shown its ugly face on every project I’ve worked on. Yes, before I got there, too.
Convoluted/untested code means changing something here might have unintended consequences that we might not see in our development environments, QA might not catch and sometimes ends up in a production environment. Writing things simply is not easy, especially at first and under pressure, but its worth is evident weeks or months down the line.
The majority of the cost of a software project is in long-term maintenance. In order to minimize the potential for defects as we introduce change, it’s critical for us to be able to understand what a system does. As systems become more complex, they take more and more time for a developer to understand, and there is an ever greater opportunity for a misunderstanding. Therefore, code should clearly express the intent of its author. The clearer the author can make the code, the less time others will have to spend understanding it. This will reduce defects and shrink the cost of maintenance.
It’s easy to think this applies only to large projects, but I can personally attest to committing these sins on smaller projects. I am still paying the price today. Sitdiary is a reminder of that. Over the past few months, I’ve taken some free time here and there to bring the very outdated code up to PHP 5.3+ standards.
Half of that battle is spent in understanding what I was trying to do at various points in the code. It’s hard not to think bad thoughts about that person, despite him being younger me.
You can express yourself by choosing good names. We want to be able to hear a class or function name and not be surprised when we discover its responsibilities. You can also express yourself by keeping your functions and classes small. Small classes and functions are usually easy to name, easy to write, and easy to understand.
This is a simple, yet effective and powerful practice. Writing a function/method name is as simple as clearly expressing its purpose and then using it specifically for that purpose. A nice benefit to this is that actual documentation isn’t absolutely needed once this is done. It’s been said many times, but self-documenting code is worth its weight in gold.
You can also express yourself by using standard nomenclature. Design patterns, for example, are largely about communication and expressiveness. By using the standard pattern names, such as COMMAND or VISITOR, in the names of the classes that implement those patterns, you can succinctly describe your design to other developers.
Well-written unit tests are also expressive. A primary goal of tests is to act as documentation by example. Someone reading our tests should be able to get a quick understanding of what a class is all about.
Just the practice of writing tests is important, but beyond that, writing a clear test is just as important as writing clear code. This is one thing I find lacking in many of the enterprise-level production applications I’ve been involved with. It’s not that companies don’t want well-tested code, it’s that it is viewed as “extra.”
The problem with this view is that they end up paying the price down the road in customer-facing bugs, customer service time, developer time, etc. It’s actually less expensive to establish the simple practice of coupling code with tests from the beginning.
But the most important way to be expressive is to try. All too often we get our code working and then move on to the next problem without giving sufficient thought to making that code easy for the next person to read. Remember, the most likely next person to read the code will be you.
Extremely well put, I think. If you’ve ever run into your old code and faced a learning curve, then you already know this. Now is the best time to start.
You’ll thank you later.