I've just finished reading Clean Code: A Handbook of Agile Software Craftsmanship by Bob Martin. Let me tell you: this book is so good. I've forgotten more things I read in this book than I ever knew before reading it. Which probably isn't saying much, but you get my drift.
So why is it so good? It's packed full to the brim with advice, principles, tips and examples of how to write code that's readable, understandable, maintainable and testable.
The first part of the book is about the principles of clean code, why one shoud write it, and what it looks like in practice. Each chapter focuses on a specific area such as variables, functions, classes, comments, each full of gems of wisdom and rules of thumb that have obviously come about through decades of experience. Each little nugget takes an overarching principle and applies it specifically to the area in question. Take for instance this snippet about try/catch blocks from Chapter 3 (Functions):
Error handling is one thing
Functions should do one thing. Error handling is one thing. Thus, a function that handles errors should do nothing else. This implies [...] that if the keyword try exists in a function, it should be the very first word in the function and that there should be nothing after the catch/finally blocks.
Seems pretty obvious, you say? That's the beauty of it: once it's pointed out to you, it's obvious, but I just never thought about it until I read that. How about this, from Chapter 4 (Comments):
Explain Yourself in Code
There are certainly times when code makes a poor vehicle for explanation. Unfortunately, many programmers have taken this to mean that code is seldom, if ever, a good means for explanation. This is patently false. Which would you rather see? This:// Check to see if the employee is eligible for full benefits if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
Or this?if (employee.isEligibleForFullBenefits())
It takes only a few seconds of thought to explain most of your intent in code. In many cases it's simple a matter of creating a function that says the same thing as the comment you want to write.
The second part of the book takes the general principles outlined in the first part and puts them into practice, with several really thorough examples of how to turn "bad" code into "good" code. The code is presented in its original form, and then you are taken step by step through the process, at each stage describing the problems with the code, the motivation behind the change, and how to change it in such a way that it still works at the end of it all.
If you're reading this as a seasoned developer and thinking "I know all this stuff, there's no need for me to get a book about it" - I would gently but firmly disagree. Even in the unlikely event that there was nothing at all that you didn't know, I'd still recommend buying it. I've read it all the way through, but I still keep it as a reference to dip in and out of, and each time I'm rewarded by something from the back of my mind being reinforced and brought to the forefront. Not to be coarse, but if you are looking for productive reading material for bathroom breaks, this book is perfect.
Anyway I guess I should stop raving about it now and do something else, but I can't recommend it enough. So stop reading this and buy it already!