The Robert C. Martin Clean Code Collection (Collection) (Robert C. Martin Series)
Rate it:
Open Preview
Kindle Notes & Highlights
5%
Flag icon
The bad news is that writing clean code is a lot like painting a picture. Most of us know when a picture is painted well or badly. But being able to recognize good art from bad does not mean that we know how to paint. So too being able to recognize clean code from dirty code does not mean that we know how to write clean code!
6%
Flag icon
make it hard for bugs to hide,
6%
Flag icon
Clean code does one thing well.
6%
Flag icon
They used the metaphor of broken windows.3 A building with broken windows looks like nobody cares about it. So other people stop caring. They allow more windows to become broken. Eventually they actively break them. They despoil the facade with graffiti and allow garbage to collect. One broken window starts the process toward decay.
John Schneider
· Flag
John Schneider
This was Rudi Giuliani’s approach to crime in NYC, where it did work was on the subway, every night all graffiti was removed, if only we could remove all shite code every night
Nick
· Flag
Nick
Related: there's a two part series of one of my favorite podcasts about the evolution of NYC crime and technology's introduction and ongoing role in the NYPD.

- https://gimletmedia.com/shows/reply-a...…
John Schneider
· Flag
John Schneider
I remember those, about the NYC cop
6%
Flag icon
Abbreviated error handling is just one way that programmers gloss over details.
6%
Flag icon
Bad code tries to do too much, it has muddled intent and ambiguity of purpose. Clean code is focused. Each function, each class, each module exposes a single-minded attitude that remains entirely undistracted, and unpolluted, by the surrounding details.
6%
Flag icon
Clean code always looks like it was written by someone who cares. There is nothing obvious that you can do to make it better.
6%
Flag icon
duplication. When the same thing is done over and over, it’s a sign that there is an idea in our mind that is not well represented in the code. I try to figure out what it is. Then I try to express that idea more clearly.
6%
Flag icon
Expressiveness goes beyond names, however. I also look at whether an object or method is doing more than one thing. If it’s an object, it probably needs to be broken into two or more objects. If it’s a method, I will always use the Extract Method refactoring on it, resulting in one method that says more clearly what it does, and some submethods saying how it is done.
6%
Flag icon
the collection abstraction often calls my attention to what’s “really” going on, and keeps me from running down the path of implementing arbitrary collection behavior when all I really need is a few fairly simple ways of finding what I want.
7%
Flag icon
The name of a variable, function, or class, should answer all the big questions. It should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.    int d; // elapsed time in days
8%
Flag icon
If you can’t pronounce it, you can’t discuss it without sounding like an idiot. “Well, over here on the bee cee arr three cee enn tee we have a pee ess zee kyew int, see?” This matters because
8%
Flag icon
Besides, people quickly learn to ignore the prefix (or suffix) to see the meaningful part of the name. The more we read the code, the less we see the prefixes.
8%
Flag icon
These are sometimes a special case for encodings. For example, say you are building an ABSTRACT FACTORY for the creation of shapes. This factory will be an interface and will be implemented by a concrete class. What should you name them? IShapeFactory and ShapeFactory? I prefer to leave interfaces unadorned. The preceding I, so common in today’s legacy wads, is a distraction at best and too much information at worst. I don’t want my users knowing that I’m handing them an interface. I just want them to know that it’s a ShapeFactory. So if I must encode either the interface or the ...more
8%
Flag icon
Classes and objects should have noun or noun phrase names like Customer, WikiPage, Account, and AddressParser. Avoid words like Manager, Processor, Data, or Info in the name of a class. A class name should not be a verb.
8%
Flag icon
When constructors are overloaded, use static factory methods with names that describe the arguments. For example,    Complex fulcrumPoint = Complex.FromRealNumber(23.0); is generally better than    Complex fulcrumPoint = new Complex(23.0);
9%
Flag icon
Use Solution Domain Names Remember that the people who read your code will be programmers. So go ahead and use computer science (CS) terms, algorithm names, pattern names, math terms, and so forth. It is not wise to draw every name from the problem domain because we don’t want our coworkers to have to run back and forth to the customer asking what every name means when they already know the concept by a different name. The name AccountVisitor means a great deal to a programmer who is familiar with the VISITOR pattern.
9%
Flag icon
When there is no “programmer-eese” for what you’re doing, use the name from the problem domain. At least the programmer who maintains your code can ask a domain expert what it means. 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.
9%
Flag icon
The function is a bit too long and the variables are used throughout. To split the function into smaller pieces we need to create a GuessStatisticsMessage class and make the three variables fields of this class. This provides a clear context for the three variables. They are definitively part of the GuessStatisticsMessage.
9%
Flag icon
The names accountAddress and customerAddress are fine names for instances of the class Address but could be poor names for classes. Address is a fine name for a class. If I need to differentiate between MAC addresses, port addresses, and Web addresses, I might consider PostalAddress, MAC, and URI. The resulting names are more precise, which is the point of all naming.
9%
Flag icon
The hardest thing about choosing good names is that it requires good descriptive skills and a shared cultural background.
10%
Flag icon
The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that.
John Schneider
· Flag
John Schneider
Sort of like the rules of fight club
10%
Flag icon
This implies that the blocks within if statements, else statements, while statements, and so on should be one line long. Probably that line should be a function call. Not only does this keep the enclosing function small, but it also adds documentary value because the function called within the block can have a nicely descriptive name. This also implies that functions should not be large enough to hold nested structures. Therefore, the indent level of a function should not be greater than one or two. This, of course, makes the functions easier to read and understand.
10%
Flag icon
FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT WELL. THEY SHOULD DO IT ONLY.
10%
Flag icon
The problem with this statement is that it is hard to know what “one thing” is. Does Listing 3-3 do one thing? It’s easy to make the case that it’s doing three things: 1. Determining whether the page is a test page. 2. If so, including setups and teardowns. 3. Rendering the page in HTML. So which is it? Is the function doing one thing or three things? Notice that the three steps of the function are one level of abstraction below the stated name of the function. We can describe the function by describing it as a brief TO4 paragraph: TO RenderPageWithSetupsAndTeardowns, we check to see whether ...more
10%
Flag icon
So, another way to know that a function is doing more than “one thing” is if you can extract another function from it with a name that is not merely a restatement of its implementation [G34].
10%
Flag icon
Look at Listing 4-7 on page 71. Notice that the generatePrimes function is divided into sections such as declarations, initializations, and sieve. This is an obvious symptom of doing more than one thing. Functions that do one thing cannot be reasonably divided into sections.
10%
Flag icon
There are concepts in there that are at a very high level of abstraction, such as getHtml(); others that are at an intermediate level of abstraction, such as: String pagePathName = PathParser.render(pagePath); and still others that are remarkably low level, such as: .append(”\n”).
10%
Flag icon
Reading Code from Top to Bottom: The Stepdown Rule We want the code to read like a top-down narrative.5 We want every function to be followed by those at the next level of abstraction so that we can read the program, descending one level of abstraction at a time as we read down the list of functions. I call this The Step-down Rule. To say this differently, we want to be able to read the program as though it were a set of TO paragraphs, each of which is describing the current level of abstraction and referencing subsequent TO paragraphs at the next level down. To include the setups and ...more
11%
Flag icon
Third, it violates the Single Responsibility Principle7 (SRP) because there is more than one reason for it to change. Fourth, it violates the Open Closed Principle8 (OCP) because it must change whenever new types are added.
11%
Flag icon
My general rule for switch statements is that they can be tolerated if they appear only once, are used to create polymorphic objects, and are hidden behind an inheritance relationship so that the rest of the system can’t see them [G23].
11%
Flag icon
“You know you are working on clean code when each routine turns out to be pretty much what you expected.”
11%
Flag icon
Don’t be afraid to make a name long.
11%
Flag icon
The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification—and then shouldn’t be used anyway.
11%
Flag icon
There are two very common reasons to pass a single argument into a function. You may be asking a question about that argument, as in boolean fileExists(“MyFile”). Or you may be operating on that argument, transforming it into something else and returning it.
11%
Flag icon
A somewhat less common, but still very useful form for a single argument function, is an event. In this form there is an input argument but no output argument. The overall program is meant to interpret the function call as an event and use the argument to alter the state of the system, for example, void passwordAttemptFailedNtimes(int attempts). Use this form with care. It should be very clear to the reader that this is an event. Choose names and contexts carefully.
11%
Flag icon
Flag arguments are ugly. Passing a boolean into a function is a truly terrible practice. It immediately complicates the signature of the method, loudly proclaiming that this function does more than one thing. It does one thing if the flag is true and another if the flag is false!
11%
Flag icon
We should have split the function into two: renderForSuite() and renderForSingleTest().
11%
Flag icon
Even obvious dyadic functions like assertEquals(expected, actual) are problematic. How many times have you put the actual where the expected should be? The two arguments have no natural ordering. The expected, actual ordering is a convention that requires practice to learn. Dyads aren’t evil, and you will certainly have to write them. However, you should be aware that they come at a cost and should take advantage of what mechanims may be available to you to convert them into monads. For example, you might make the writeField method a member of outputStream so that you can say outputStream. ...more
12%
Flag icon
When a function seems to need more than two or three arguments, it is likely that some of those arguments ought to be wrapped into a class of their own. Consider, for example, the difference between the two following declarations:    Circle makeCircle(double x, double y, double radius);    Circle makeCircle(Point center, double radius); Reducing the number of arguments by creating objects out of them may seem like cheating, but it’s not. When groups of variables are passed together, the way x and y are in the example above, they are likely part of a concept that deserves a name of its own.
12%
Flag icon
arguments. In the case of a monad, the function and argument should form a very nice verb/noun pair. For example, write(name) is very evocative. Whatever this “name” thing is, it is being “written.” An even better name might be writeField(name), which tells us that the “name” thing is a “field.” This last is an example of the keyword form of a function name. Using this form we encode the names of the arguments into the function name. For example, assertEquals might be better written as assertExpectedEqualsActual(expected, actual). This strongly mitigates the problem of having to remember the ...more
12%
Flag icon
Anything that forces you to check the function signature is equivalent to a double-take. It’s a cognitive break and should be avoided.
12%
Flag icon
If your function must change the state of something, have it change the state of its owning object.
12%
Flag icon
Command Query Separation Functions should either do something or answer something, but not both. Either your function should change the state of an object, or it should return some information about that object.
12%
Flag icon
Prefer Exceptions to Returning Error Codes Returning error codes from command functions is a subtle violation of command query separation. It promotes commands being used as expressions in the predicates of if statements.
Nick
· Flag
Nick
The number of times I've passed back ints or tuples makes me feel dirty now! Nothing left to do but wander from file to file muttering "out damn spot" and refactoring.
John Schneider
· Flag
John Schneider
Exceptions take a lot of work, lots of definitions handlers finals and cleanup
Nick
· Flag
Nick
True, and this does kind of clash with the statement to "keep exceptions exceptional". But when I think back to the amount of times that I've cluttered up several layers of function calls with logic t…
12%
Flag icon
if you use exceptions instead of returned error codes, then the error processing code can be separated from the happy path code and can be simplified:
12%
Flag icon
Functions should do one thing. Error handing is one thing. Thus, a function that handles errors should do nothing else. This implies (as in the example above) 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.
12%
Flag icon
Returning error codes usually implies that there is some class or enum in which all the error codes are defined.    public enum Error {       OK,       INVALID,       NO_SUCH,       LOCKED,       OUT_OF_RESOURCES,              WAITING_FOR_EVENT;    } Classes like this are a dependency magnet; many other classes must import and use them. Thus, when the Error enum changes, all those other classes need to be recompiled and redeployed.11 This puts a negative pressure on the Error class. Programmers don’t want to add new errors because then they have to rebuild and redeploy everything. So they ...more
12%
Flag icon
When you use exceptions rather than error codes, then new exceptions are derivatives of the exception class. They can be added without forcing any recompilation or redeployment.12
13%
Flag icon
Structured programming, Aspect Oriented Programming, Component Oriented Programming, are all, in part, strategies for eliminating duplication.
« Prev 1 3