Reviews

Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin

fbroom's review

Go to review page

5.0

Great Book, I would advise though to not get it on the kindle because reading large unformatted code on the kindle is impossible.
I still managed to learn a lot. (I read about 70% of the book)

I have a lot of notes:

3 Functions
1. Each function does one thing (Single Responsibility principle)
2. Statements within our functions should all be at the same level of abstraction
3. Functions should be short (20 lines of code)
4. Use descriptive names
5. Open closed principle (it will not change whenever new types are added)
6. Return a value, don’t use an output argument. In OO you don’t need them
7. Flag arguments are ugly, it implies the function is doing more than one thing break into two functions instead (if (key == update) else if (key == delete) ….)
8. User Exceptions rather than returning errors
9. Don’t repeat yourself (DRY)

4 Comments
1. When you have comments, it only means that you can’t express yourself through the code clearly. it means failure. Other examples of bad comments:
* Redundant comments
* Journal comments
* Noise comments
* Misleading comments
* Position marker, example: //////// Actions ///////
* Closing braces comments // if // while. it means code is unreadable
* Commenting code (makes no sense with version control)
* System wide information (comments should be local to that specific method)
* Too much information
2. Comments can be good sometimes (explanation of intent, clarifications if it’s out of hand (external library return codes), warnings, TODO comments)

5 Formatting
1. Small files are desirable, makes the code easier to understand
2. Adding blank lines between different concepts helps readability
3. Concepts close to each other should be kept vertically close to each other
4. Variables should be declared close to their usage as possible, if functions are small, they should appear at the top of each function
5. Control variables for loops should usually be declared within the loop statement
6. Instance variables should be declared at the top of the class
7. It is nice to have a function call dependencies to point in the downward direction (doesn’t apply to C, C++)
8. Lines should be short. you should never have to scroll to the right.
9. Unaligned declarations are better! yes!
10. no space between function name and its arguments
11. Indentation
12.
Factors don’t need spaces 2*a - 4*b + 3*c instead of 2 * b - 4 * b + 3 * c

6 Objects and Data Structures
1. Data Abstraction, hiding details and exposing abstractions is preferred, it’s not just about adding getting and setters, some thought is needed
2. Data Structures vs Objects. Example: You can make simple data structures (circle, rectangle, square) and then have some functions that would determine for example the area based on the type (if square, if circle). In this scenario (data structures) adding a new function will not change the data structures while adding a new shape will require that all functions change. In OO, you make a polymorphic area function and add it it to all shapes. Adding a new function is hard because you will change all the classes while adding a new shape is easy
3. The Law of Demeter: a method f of class C should only call methods in C, an object created by f, an object passed to f as an argument, an object held in an instance variable of C.


7 Error Handling
1. Don't return null! Just return an empty list and save yourself from checking if the return value is null
2. Don't pass null (worse than returning a null) maybe assertions but still review your code before passing null


8 Boundaries
1. Instead of asking your users to cast the variable to which ever type they need. It should be done in your class thru a method they can access (the sensors example)
2. Don’t pass boundary interfaces (like Maps in Java or third party ones like log4j), instead create an interface and make maintenance easy when the third party code changes
3. Write test code for third party apps that you use instead of learning how it works! Third party code should accessible from an interface (some boundary) so that when third party code changes we are safe


9 Unit Tests
1. Unit tests are first-class citizens
2. Clean tests are readable
3. One assert per test
4. Single concept per test
5. Tests should be fast
6. Tests should be independent
7. Tests should be repeatable in any environment
8. Tests should have a Boolean output
9. Tests should be written before production code


10 Classes
1. Classes should be small
2. Classes should have a single responsibility
3. Classes should have a small number of instance variables

11 Systems
1. An object should not take responsibility for instantiating dependencies itself
2. "It’s a myth that we can get systems right the first time, instead we should implement today’s stories then refactor and expand the system to implement new stories tomorrow. “incremental agility””
3. Use standards when they add demonstrable value
4. systems need domain-specific languages

12 Emergence
1. A design is simple if {runs all the tests, contains no duplications, expresses the intent of the programmer, minimizes the number of classes and methods}

13 Concurrency
1. Concurrency incurs some overhead, both in performance as well as writing additional code
2. Correct concurrency is complex
3. Concurrency often require a fundamental change in design strategy.
4. Keep concurrency related code separate from other code
5. Sometimes it is easier to use copies of data instead of sharing them
6. Use the synchronized keyword
7. Threads should be as independent as possible.
8. Know your library
9. Know your execution model
10. Don't use more than one method on a shared resource.
11. Keep your synchronized sections small
12. Try different platforms

14 Successive Refinement
This chapter is simply unreadable on the kindle. It’s the author’s large piece and code and the way he was able to refactor it and make it better.

1. One of the best ways to ruin the program is to make massive changes to its structure in the name of improvement, to avoid it use tests! and small incremental changes instead


15 JUnit Internals
Skipped

16 Refactoring SerialDate
Code review of David Gilbert’s SerialDate Class, again it hard to read this on a kindle


17 Smells and Heuristics
List of smells

1. Comments:
* Inappropriate comments
* obsolete comments
* redundant comments
* poorly written comments
* commented-out code
2. Environment:
* build requires more than one step
* tests require more than one step
3. Functions:
* too many arguments
* output arguments
* dead functions (never called)
4. General:
* multiple language in one source file
* obvious behavior is unimplemented
* incorrect behavior at the boundaries
* overridden safeties
* duplication
* code at wrong level of abstraction
* base classes depending on their derivates
* too much information (interfaces giving so much)
* dead code (code never executed)
* vertical separation
* inconsistency
* clutter
* artificial coupling (not needed)
* inappropriate static (when in doubt, make it non-static)
* use explanatory variables
* functions names should say what they do
* understand the algorithm
* prefer polymorphism to if/else or switch/case
* follow standard conventions
* replace magic numbers with named constants
* be precise (NO for using floats for currencies!)
* encapsulate conditionals
* avoid negative conditionals
* functions should do one thing
* don’t be arbitrary
* encapsulate boundary conditions
* functions should descend only one level of abstraction
* keep configurable data at a high level
* avoid transitive navigation
5. Java

* Avoid using long imports by using wild cards
* don’t inherit constants
* constants vs enums (use enums)

6. Names

* Use descriptive names (no i, j or k)
* Choose names at the appropriate level of abstractions
* use standard nomenclature where possible
* use unambiguous names
* use long names for long scopes (tiny names are okay for tiny scopes)
* avoid encodings (m_, s_)
* names should describe side-effects

7. Tests

* test everything
* use a coverage tool (to find modules that are not tested)
* don’t skip trivial tests
* an ignored test is a question about an ambiguity
* test boundary conditions
* exhaustively test near bugs
* patterns of failures are revealing (if tests are failing in a certain pattern, helps)
* test convergence patterns can be revealing
* tests should be fast


llanirev's review

Go to review page

3.0

Good practices and stuff every software engineer should adhere to, but the book is full with open doors. As a advanced Software Engineer you should already know these practices; either by logical thinking or thought by your peers or coach.

brycestevenwilley's review

Go to review page

informative slow-paced

2.0

Eh, not worth reading. Good advice, sure, but there's so many wack examples and difficult/annoying to read/poorly formatted refactors, and outdated Java code (similar to the Elements of Java Style) that I strongly felt like I was wasting my time. Read some blogs about naming variables instead.

cllamach's review

Go to review page

5.0

An incredible book that leaves with you a sense of pride in writing good and understandable code. I think that is a topic that you don't see in the programming courses in college a lot. You get teach how to program, that there are an infinity number of ways to get to the same solution, but you never are given a set of standards to improve that solution once you have it. It's more like mash something together, if it works for one or two cases great, move on to the next problem.

There needs to be a sense of pride in the code as the secondary product we are creating (the primary being the product/service). It's pretty much a presentation card for whoever comes after us when we are finished with a project.

hellomateyboy's review

Go to review page

informative medium-paced

3.75

Some chapters are really informative with great suggestions. Some of it feels slightly outdated 

andrencosta's review

Go to review page

informative slow-paced

4.0

antonybarnet's review against another edition

Go to review page

reflective relaxing medium-paced

4.0

rodhilton's review

Go to review page

4.0

There is a movement brewing in the world of professional software development. This movement is concerned not merely with writing functional, correct code, but also on writing good code. Taking pride in code. This movement is the Software Craftsmanship movement, and one of the people near the head of this movement is Robert C. Martin, also known as Uncle Bob.

His book "Clean Code" is, in many ways, an introduction to the concept of Software Craftsmanship and a guide for developers interested in becoming craftsmen. Clean Code is not about only writing correct code, it's about writing code that is designed well, code that reads well, and code that expresses the intent of the author.

The book is essentially divided into two parts. The first part contains Bob's suggestions for writing and maintaining clean code. This includes suggestions on everything ranging from how to properly comment code and how to properly name variables to how to separate your classes and how to construct testable concurrent code. The second part of the book uses the principles in the first part to guide the reader through a few exercises in which existing code is cleaned.

The first part of the book is fantastic. I can't recommend it highly enough for a professional software developer that wishes to elevate him or herself to a higher standard. This guide is excellent, and gave me lots of things to think about while reading it. I could almost feel myself becoming a better programmer as I internalized Martin's advice, and the code I've been writing has been noticeably better since I began following his suggestions.

In the second part of the book, Martin essentially guides us through three projects: a command line argument parser he wrote, a section of the JUnit source code, and a section of source code from SerialDate. Of these, the most detailed guide is Martin's illustration of refactoring the command line argument parser.

These sections all suffered from a fundamental flaw: they were inside a book.

These sections all required reading large amounts of source code. Not just scanning it, but really reading and understanding the code, so that the reader can understand the changes Martin makes to the code. Reading and understanding code is something I do every day as a professional, but I never have to do it from paper.

When I read code, I'm interacting with something, not just reading. I can scroll up and down. If I see a method being used and I wonder how it's written, I can click on it and jump right to the implementation. My IDE shows me symbols in my gutterbar when methods are overridden. I can press a keystroke to pull up a list of just the methods in a source file. I can right click on a method and find its usages immediately. The source code I am reading is something I can push and pull, gaining an understanding of it through interaction.

When source code is printed in a book, you get none of this. To make matters worse, Martin's code samples have absolutely no syntax highlighting applied to them. When I read source code, certain parts are rendered in specific ways that make it easier to pull the information into my brain. Strings and literals are formatted differently, comments are dimmer so I can focus on code, and so on. Code samples in "Clean Code" are just characters, with occasionally bolding used to draw attention to parts that were changed. It's amazing how much syntax highlighting helps make code more comprehensible, even at a completely subconscious level.

A book is, quite simply, not an appropriate medium for a guided code walkthrough. I'd have preferred the content of these sections as perhaps a lecture, with Martin's text done in audio and his code kept on the screen. This would at least prevent me from having to flip back and forth constantly. I didn't get as much out of these sections as I would have liked to, simply because it was so difficult to digest the information it contained in such an awkward, unnatural medium. At the very least, the code samples should have been printed in color, with syntax highlighting.

I can tell that his advice was good and that the refactorings he applied to the code samples in the book made the code far better, but mostly because I've observed these efforts in real life and observed how much they improve code. If I were to encounter Martin's "before" and "after" code in a project I was working on, I undoubtedly would find the "after" code far, far cleaner and more enjoyable to work with. However, since the book format made it so difficult to understand EITHER code sample, it didn't seem like Martin's efforts offered much improvement, even though I know they did.

Despite this frustration, the book is an excellent read, and I'm quite certain it has contributed a great deal to helping me improve as a professional. I can't recommend it enough, especially for Java developers. I just think that most readers will find the final few chapters intensely frustrating - I recommend downloading the code and viewing it in your favorite code editor so that you can comprehend the source code the way you would any other source code.

mzoli's review

Go to review page

2.0

Good for reviewing most of clean code tips, especially dirty code smells. Well detailed and with sufficient code samples(BTW all the code samples are written in java).
But all along I had problems with accepting some of the rules at the extent that author implies. Even in my opinion some refactoring examples shown in the book were making the code harder to read compared to former state.
I think and probably the writer agrees that clean code is not some sacred thing by itself, but it serves high quality and maintainable software. So as not an experienced developer and one who never had worked on huge code bases. I think some of these rules wont serve the desired goal at least in software with small code base.
Also I think some of the rules don't apply today because we now have more intelligent code editors with better autocompletion and code hinting(showing the docs, definition, etc).
My objections are mostly on parts that the author argues the code is not clean because the lack of expressiveness. I don’t see why I should have long expressive names that any usual developer won't need that degree after a week or two working on the code base and it's not just not needing it, It makes development slower. Small functions that are only used one time won’t smooth development always.
I agree expressiveness helps new coders on first steps, but it makes old developers slower. So I think at the end it's a matter of compromise and it differs case by case. For example in the case of software driven by open source community may be the case that we should make it as easy as possible for newcomers, but when there is a software with permanent team behind it I think we should make it so they can code and work faster. They don't need expressiveness because they are struggling with the code at least every week.
An example which also will bring up what I mentioned as modern code editors is about comments. The writer emphasizes that code should not need comment and it should explain it self. I don’t get it. Now days code editors show variable, functions comments as their documentation then why we shouldn’t use one line comments instead of making the code self expressive by long names, additional functions and etc.
I don't know about others but for me long lines of code is hard to read.

greenadex's review

Go to review page

4.0

4.5