More on this book
Community
Kindle Notes & Highlights
Read between
January 29 - February 3, 2021
Writing clean code is what you must do in order to call yourself a professional. There is no reasonable excuse for doing anything less than your best.
Yet attentiveness to detail is an even more critical foundation of professionalism than is any grand vision. First, it is through practice in the small that professionals gain proficiency and trust for practice in the large. Second, the smallest bit of sloppy construction, of the door that does not close tightly or the slightly crooked tile on the floor, or even the messy desk, completely dispels the charm of the larger whole. That is what clean code is about.
“But wait!” you say. “If I don’t do what my manager says, I’ll be fired.” Probably not. Most managers want the truth, even when they don’t act like it. Most managers want good code, even when they are obsessing about the schedule. They may defend the schedule and requirements with passion; but that’s their job. It’s your job to defend the code with equal passion.
When hand-washing was first recommended to physicians by Ignaz Semmelweis in 1847, it was rejected on the basis that doctors were too busy and wouldn’t have time to wash their hands between patient visits.
Clean code always looks like it was written by someone who cares.
It is not the language that makes programs appear simple. It is the programmer that make the language appear simple!
The @author field of a Javadoc tells us who we are. We are authors. And one thing about authors is that they have readers. Indeed, authors are responsible for communicating well with their readers. The next time you write a line of code, remember you are an author, writing for readers who will judge your effort.
the ratio of time spent reading vs. writing is well over 10:1. We are constantly reading old code as part of the effort to write new code.
making it easy to read actually makes it easier to write.
If a name requires a comment, then the name does not reveal its intent.
Distinguish names in such a way that the reader knows what the differences offer.
programming is a social activity.
One difference between a smart programmer and a professional programmer is that the professional understands that clarity is king. Professionals use their powers for good and write code that others can understand.
Say what you mean. Mean what you say.
Our goal, as authors, is to make our code as easy as possible to understand. We want our code to be a quick skim, not an intense study. We want to use the popular paperback model whereby the author is responsible for making himself clear and not the academic model where it is the scholar’s job to dig the meaning out of the paper.
Separating solution and problem domain concepts is part of the job of a good programmer and designer. The code that has more to do with problem domain concepts should have names drawn from the problem domain.
The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that.
The parts we ignore are where the bugs will hide.
Anything that forces you to check the function signature is equivalent to a double-take. It’s a cognitive break and should be avoided.
The art of programming is, and has always been, the art of language design.
“Don’t comment bad code—rewrite it.”
The proper use of comments is to compensate for our failure to express ourself in code.
Comments are always failures. We must have them because we cannot always figure out how to express ourselves without them, but their use is not a cause for celebration.
It is possible to make the point that programmers should be disciplined enough to keep the comments in a high state of repair, relevance, and accuracy. I agree, they should. But I would rather that energy go toward making the code so clear and expressive that it does not need the comments in the first place.
Any comment that forces you to look in another module for the meaning of that comment has failed to communicate to you and is not worth the bits it consumes.
Rather than venting in a worthless and noisy comment, the programmer should have recognized that his frustration could be resolved by improving the structure of his code.
Replace the temptation to create noise with the determination to clean your code. You’ll find it makes you a better and happier programmer.
The purpose of a comment is to explain code that does not explain itself. It is a pity when a comment needs its own explanation.
communication is the professional developer’s first order of business.
The functionality that you create today has a good chance of changing in the next release, but the readability of your code will have a profound effect on all the changes that will ever be made. The coding style and readability set precedents that continue to affect maintainability and extensibility long after the original code has been changed beyond recognition. Your style and discipline survives, even though your code does not.
Objects hide their data behind abstractions and expose functions that operate on that data. Data structure expose their data and have no meaningful functions.
class names including weasel words like Processor or Manager or Super often hint at unfortunate aggregation of responsibilities.
Getting software to work and making software clean are two very different activities. Most of us have limited room in our heads, so we focus on getting our code to work more than organization and cleanliness. This is wholly appropriate. Maintaining a separation of concerns is just as important in our programming activities as it is in our programs. The problem is that too many of us think that we are done once the program works. We fail to switch to the other concern of organization and cleanliness. We move on to the next problem rather than going back and breaking the overstuffed classes into
...more
Every sizable system will contain a large amount of logic and complexity. The primary goal in managing such complexity is to organize it so that a developer knows where to look to find things and need only understand the directly affected complexity at any given time. In contrast, a system with larger, multipurpose classes always hampers us by insisting we wade through lots of things we don’t need to know right now.
In an ideal system, we incorporate new features by extending the system, not by making modifications to existing code.
“Complexity kills. It sucks the life out of developers, it makes products difficult to plan, build, and test.”
Software systems are unique compared to physical systems. Their architectures can grow incrementally, ifwe maintain the proper separation of concerns.
system might have a perfect design on paper, but if there is no simple way to verify that the system actually works as intended, then all the paper effort is questionable.
Writing tests leads to better designs.
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.
You should not need a sequence of arcane commands or context dependent scripts in order to build the individual elements.
When an obvious behavior is not implemented, readers and users of the code can no longer depend on their intuition about function names. They lose their trust in the original author and must fall back on reading the details of the code.
Code should be placed where a reader would naturally expect it to be.
most people use switch statements because it’s the obvious brute force solution, not because it’s the right solution for the situation.
There may be no more than one switch statement for a given type of selection. The cases in that switch statement must create polymorphic objects that take the place of other such switch statements in the rest of the system.
Ambiguities and imprecision in code are either a result of disagreements or laziness. In either case they should be eliminated.
The statements within a function should all be written at the same level of abstraction, which should be one level below the operation described by the name of the function.
Separating levels of abstraction is one of the most important functions of refactoring, and it’s one of the hardest to do well.
Don’t pick names that communicate implementation; choose names the reflect the level of abstraction of the class or function you are working in.