# Robert C. Martin - Clean Code (Highlights)

## Metadata
**Review**:: [readwise.io](https://readwise.io/bookreview/56986893)
**Source**:: #from/readwise #from/zotero
**Zettel**:: #zettel/fleeting
**Status**:: #x
**Authors**:: [[Robert C. Martin]]
**Full Title**:: Clean Code
**Category**:: #books #readwise/books
**Category Icon**:: 📚
**Highlighted**:: [[2025-12-21]]
**Created**:: [[2025-12-27]]
## Highlights
### Foreword
- Small things matter. This is a book about humble concerns whose value is nonetheless far from small. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=UQ34NMS5)) ^968394482
- In software, 80% or more of what we do is quaintly called “maintenance”: the act of repair. Rather than embracing the typical Western focus on producing good software, we should be thinking more like home repairmen in the building industry, or auto mechanics in the automotive field. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=XMQYJLTS)) ^968394483
Even in the AI era.
- As we maintain automobiles and other machines under TPM, breakdown maintenance—waiting for bugs to surface—is the exception. Instead, we go up a level: inspect the machines every day and fix wearing parts before they break, or do the equivalent of the proverbial 10,000-mile oil change to forestall wear and tear. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=ZIKXVGPW)) ^968394484
- The French poet Paul Valery advises us that a poem is never done and bears continual rework, and to stop working on it is abandonment. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=GUU2VAB5)) ^968394485
- Quality is the result of a million selfless acts of care—not just of any great method that descends from the heavens. That these acts are simple doesn’t mean that they are simplistic, and it hardly means that they are easy. They are nonetheless the fabric of greatness and, more so, of beauty, in any human endeavor. To ignore them is not yet to be fully human. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=6CCJKSC3)) ^968394486
### Clean Code
- That soon all code will be generated instead of written. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=XT6V6GJY)) ^968394488
AI era is coming.
- We’ve all looked at the mess we’ve just made and then have chosen to leave it for another day. We’ve all felt the relief of seeing our messy program work and deciding that a working mess is better than nothing. We’ve all said we’d go back and clean it up later. Of course, in those days we didn’t know LeBlanc’s law: Later equals never. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=FUV85DW3)) ^968394489
- Programmers face a conundrum of basic values. All developers with more than a few years experience know that previous messes slow them down. And yet all developers feel the pressure to make messes in order to meet deadlines. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=5XV2SH57)) ^968394490
- I like my code to be elegant and efficient. The logic should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations. Clean code does one thing well. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=LRN9HZC8)) ^968394491
- Apparently Bjarne thinks that clean code is pleasing to read. Reading it should make you smile the way a well-crafted music box or well-designed car would. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=H2UKMZWM)) ^968394492
- Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer’s intent but rather is full of crisp abstractions and straightforward lines of control. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=4AKA4L44)) ^968394493
- Reading clean code will never be quite like reading Lord of the Rings. Still, the literary metaphor is not a bad one. Like a good novel, clean code should clearly expose the tensions in the problem to be solved. It should build those tensions to a climax and then give the reader that “Aha! Of course!” as the issues and tensions are resolved in the revelation of an obvious solution. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=ZXDLIJMD)) ^968394494
- Dave is right. Code, without tests, is not clean. No matter how elegant it is, no matter how readable and accessible, if it hath not tests, it be unclean. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=7LYG83IB)) ^968394495
- Clean code always looks like it was written by someone who cares. There is nothing obvious that you can do to make it better. All of those things were thought about by the code’s author, and if you try to imagine improvements, you’re led back to where you are, sitting in appreciation of the code someone left for you—code left by someone who cares deeply about the craft. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=R3NK9MVL)) ^968394496
- You can call it beautiful code when the code also makes it look like the language was made for the problem. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=PY9HGGI6)) ^968394497
- You get the drift. Indeed, 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.
Because this ratio is so high, we want the reading of code to be easy, even if it makes the writing harder. Of course there’s no way to write code without reading it, so making it easy to read actually makes it easier to write. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=FECRJ2NK)) ^968394498
- Leave the campground cleaner than you found it. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=GQFJSYSM)) ^968394499
The Boy Scout Rule
### Meaningful Names
- If a name requires a comment, then the name does not reveal its intent. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=BR25BWDT)) ^968394501
- Do not refer to a grouping of accounts as an accountList unless it’s actually a List. The word list means something specific to programmers. If the container holding the accounts is not actually a List, it may lead to false conclusions.1 So accountGroup or bunchOfAccounts or just plain accounts would be better. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=2I2WQG4M)) ^968394502
- As we’ll see later on, even if the container is a List, it’s probably better not to encode the container type into the name. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=BDHAM3E7)) ^968394503
- Beware of using names which vary in small ways. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=HM9SDBMU)) ^968394504
- Noise words are another meaningless distinction. Imagine that you have a Product class. If you have another called ProductInfo or ProductData, you have made the names different without making them mean anything different. Info and Data are indistinct noise words like a, an, and the. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=V43CR2NB)) ^968394505
- In the absence of specific conventions, the variable moneyAmount is indistinguishable from money, customerInfo is indistinguishable from customer, accountData is indistinguishable from account, and theMessage is indistinguishable from message. Distinguish names in such a way that the reader knows what the differences offer. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=QFIAZTEZ)) ^968394506
- Humans are good at words. A significant part of our brains is dedicated to the concept of words. And words are, by definition, pronounceable. It would be a shame not to take advantage of that huge portion of our brains that has evolved to deal with spoken language. So make your names pronounceable. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=QRB9IE6Q)) ^968394507
- The length of a name should correspond to the size of its scope ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=DS5UMKK4)) ^968394508
- We have enough encodings to deal with without adding more to our burden. Encoding type or scope information into names simply adds an extra burden of deciphering. It hardly seems reasonable to require each new employee to learn yet another encoding “language” in addition to learning the (usually considerable) body of code that they’ll be working in. It is an unnecessary mental burden when trying to solve a problem. Encoded names are seldom pronounceable and are easy to mis-type. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=ZHXY7UYJ)) ^968394509
- You also don’t need to prefix member variables with m_ anymore. Your classes and functions should be small enough that you don’t need them. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=SIX9WHBY)) ^968394510
- So if I must encode either the interface or the implementation, I choose the implementation. Calling it ShapeFactoryImp, or even the hideous CShapeFactory, is preferable to encoding the interface. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=XLCNTNYB)) ^968394511
- If names are too clever, they will be memorable only to people who share the author’s sense of humor, and only as long as these people remember the joke. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=WRYH8YL4)) ^968394512
- Say what you mean. Mean what you say. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=XNGF323A)) ^968394513
- Pick one word for one abstract concept and stick with it. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=D7AJ9KSB)) ^968394514
#actionable
Hard for big project. AI can be a remedy.
Actionable: AI prompt to ensure consistent word per concept.
- 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. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=WGC7MFHZ)) ^968394515
### Functions
- Lines should not be 150 characters long. Functions should not be 100 lines long. Functions should hardly ever be 20 lines long. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=BZMAE76U)) ^968394517
- 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. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=8CTY6C7Z)) ^968394518
- If a function does only those steps that are one level below the stated name of the function, then the function is doing one thing. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=PKYPJ8BM)) ^968394519
Write code as nested list.
- 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]. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=N5Z4FEPD)) ^968394520
- 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. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=Q8ZFKY5G)) ^968394521
top-down
- The solution to this problem (see Listing 3-5) is to bury the switch statement in the basement of an ABSTRACT FACTORY,9 and never let anyone see it. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=8K8M2U29)) ^968394522
You cannot avoid complexity, you hide it somewhere else
- Choosing descriptive names will clarify the design of the module in your mind and help you to improve it. It is not at all uncommon that hunting for a good name results in a favorable restructuring of the code. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=4NCWGKF4)) ^968394523
- 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. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=SB66PSCQ)) ^968394524
- 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. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=PHQHCQL4)) ^968394525
- 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). ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=JSPSW2C6)) ^968394526
- 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! ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=HUJL2DF4)) ^968394527
- Even obvious dyadic functions like assertEquals(expected, actual) are problematic. How many times have you put the actual where the expected should be? ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=47TAMMPE)) ^968394528
- 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. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=F37CIAUC)) ^968394529
- If the variable arguments are all treated identically, as they are in the example above, then they are equivalent to a single argument of type List. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=4NITCKAP)) ^968394530
- 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 ordering of the arguments. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=69DRDCRK)) ^968394531
Objective-C way
- Anything that forces you to check the function signature is equivalent to a double-take. It’s a cognitive break and should be avoided. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=BSLHWNGT)) ^968394532
- In general output arguments should be avoided. If your function must change the state of something, have it change the state of its owning object. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=4QRPHI83)) ^968394533
- 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. Doing both often leads to confusion. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=Q776SUQY)) ^968394534
- The art of programming is, and has always been, the art of language design. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=AT4UY64H)) ^968394535
- Master programmers think of systems as stories to be told rather than programs to be written. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=FDDDSGD6)) ^968394536
### Comments
- The proper use of comments is to compensate for our failure to express ourself in code. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=THDQQTUJ)) ^968394538
- It is just plain silly to have a rule that says that every function must have a javadoc, or every variable must have a comment. Comments like this just clutter up the code, propagate lies, and lend to general confusion and disorganization. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=4PZXGE9E)) ^968394539
### Formatting
- Think of a well-written newspaper article. You read it vertically. At the top you expect a headline that will tell you what the story is about and allows you to decide whether it is something you want to read. The first paragraph gives you a synopsis of the whole story, hiding all the details while giving you the broad-brush concepts. As you continue downward, the details increase until you have all the dates, names, quotes, claims, and other minutia. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=HWRY45DQ)) ^968394541
- If one function calls another, they should be vertically close, and the caller should be above the callee, if at all possible. This gives the program a natural flow. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=RL7A2SER)) ^968394542
- As in newspaper articles, we expect the most important concepts to come first, and we expect them to be expressed with the least amount of polluting detail. We expect the low-level details to come last. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=WBUI6PZR)) ^968394543
- If I have long lists that need to be aligned, the problem is the length of the lists, not the lack of alignment. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=UAVWNPRS)) ^968394544
### Objects and Data Structures
- In any complex system there are going to be times when we want to add new data types rather than new functions. For these cases objects and OO are most appropriate. On the other hand, there will also be times when we’ll want to add new functions as opposed to data types. In that case procedural code and data structures will be more appropriate. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=6QUVUDUA)) ^968394546
- The method should not invoke methods on objects that are returned by any of the allowed functions. In other words, talk to friends, not to strangers. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=FHU9SIKR)) ^968394547
### Error Handling
- The code is better because two concerns that were tangled, the algorithm for device shutdown and error handling, are now separated. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=PBB4SQKK)) ^968394549
- In this case, because we know that the work that we are doing is roughly the same regardless of the exception, we can simplify our code considerably by wrapping the API that we are calling and making sure that it returns a common exception type ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=GSVZE54D)) ^968394550
- This is called the SPECIAL CASE PATTERN [Fowler]. You create a class or configure an object so that it handles a special case for you. When you do, the client code doesn’t have to deal with exceptional behavior. That behavior is encapsulated in the special case object. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=AH5CZ96E)) ^968394551
### Boundaries
- What if we took a different approach? Instead of experimenting and trying out the new stuff in our production code, we could write some tests to explore our understanding of the third-party code. Jim Newkirk calls such tests learning tests. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=NTXNZI3L)) ^968394553
- To keep from being blocked, we defined our own interface. We called it something catchy, like Transmitter. We gave it a method called transmit that took a frequency and a data stream. This was the interface we wished we had. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=CT7BWYSH)) ^968394554
Inverse dependency
### Unit Tests
- Fast Tests should be fast. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=NDZYZA6N)) ^968394556
F.I.R.S.T
- Independent Tests should not depend on each other. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=7I4YU4RX)) ^968394557
F.I.R.S.T
- Repeatable Tests should be repeatable in any environment. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=GDXY39XX)) ^968394558
F.I.R.S.T
- Self-Validating The tests should have a boolean output. Either they pass or fail. You should not have to read through a log file to tell whether the tests pass. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=4TPJNNH4)) ^968394559
F.I.R.S.T
- Timely The tests need to be written in a timely fashion. Unit tests should be written just before the production code that makes them pass. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=95P58WND)) ^968394560
F.I.R.S.T
### Classes
- We should also be able to write a brief description of the class in about 25 words, without using the words “if,” “and,” “or,” or “but.” ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=Z4TSAY2E)) ^968394562
- In general the more variables a method manipulates the more cohesive that method is to its class. A class in which each variable is used by each method is maximally cohesive. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=39H5RKEC)) ^968394563
- Private method behavior that applies only to a small subset of a class can be a useful heuristic for spotting potential areas for improvement. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=M3XG8Q3H)) ^968394564
### Systems
- However, the process of creating standards can sometimes take too long for industry to wait, and some standards lose touch with the real needs of the adopters they are intended to serve. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=JVAM84ER)) ^968394566
### Emergence
- “ ^968394568
- Runs all the tests
- Contains no duplication
- Expresses the intent of the programmer
- Minimizes the number of classes and methods”
- Once we have tests, we are empowered to keep our code and classes clean. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=HT7R4U5Q)) ^968394569
- 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. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=PUH4DAW7)) ^968394570
### Concurrency
- Keep your concurrency-related code separate from other code. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=S96ZFGNK)) ^968394572
- Make your thread-based code especially pluggable so that you can run it in various configurations. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=MDWXGLB4)) ^968394573
### Successive Refinement
- To write clean code, you must first write dirty code and then clean it. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=DMGNFQRX)) ^968394575
### Smells and Heuristics
- Building a project should be a single trivial operation. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=AKFNCESD)) ^968394577
- You should be able to run all the unit tests with just one command. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=6KCSIG6C)) ^968394578
- Notice that level+1 appears twice. This is a boundary condition that should be encapsulated within a variable named something like nextLevel. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=DFT4FEZS)) ^968394579
- 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. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=H9WB524B)) ^968394580
- The length of a name should be related to the length of the scope. You can use very short variable names for tiny scopes, but for big scopes you should use longer names. ([View Highlight](zotero://open-pdf/library/items/H7IHWR67?annotation=YNXAULYT)) ^968394581