Even bad code can function. But if code isn’t clean, it can bring a development organization to its knees. Every year, countless hours and significant resources are lost because of poorly written code. But it doesn’t have to be that way.
Noted software expert Robert C. Martin presents a revolutionary paradigm with Clean Code: A Handbook of Agile Software Craftsmanship . Martin has teamed up with his colleagues from Object Mentor to distill their best agile practice of cleaning code “on the fly” into a book that will instill within you the values of a software craftsman and make you a better programmer—but only if you work at it.
What kind of work will you be doing? You’ll be reading code—lots of code. And you will be challenged to think about what’s right about that code, and what’s wrong with it. More importantly, you will be challenged to reassess your professional values and your commitment to your craft.
Clean Code is divided into three parts. The first describes the principles, patterns, and practices of writing clean code. The second part consists of several case studies of increasing complexity. Each case study is an exercise in cleaning up code—of transforming a code base that has some problems into one that is sound and efficient. The third part is the payoff: a single chapter containing a list of heuristics and “smells” gathered while creating the case studies. The result is a knowledge base that describes the way we think when we write, read, and clean code.
Readers will come away from this book understanding
- How to tell the difference between good and bad code
- How to write good code and how to transform bad code into good code
- How to create good names, good functions, good objects, and good classes
- How to format code for maximum readability
- How to implement complete error handling without obscuring code logic
- How to unit test and practice test-driven development
About the Author
Robert C. “Uncle Bob” Martin has been a software professional since 1970 and an international software consultant since 1990. He is founder and president of Object Mentor, Inc., a team of experienced consultants who mentor their clients worldwide in the fields of C++, Java, C#, Ruby, OO, Design Patterns, UML, Agile Methodologies, and eXtreme programming.
Table of Contents
On the Cover xxix
Chapter 1: Clean Code 1
There Will Be Code 2
Bad Code 3
The Total Cost of Owning a Mess 4
Schools of Thought 12
We Are Authors 13
The Boy Scout Rule 14
Prequel and Principles 15
Chapter 2: Meaningful Names 17
Use Intention-Revealing Names 18
Avoid Disinformation 19
Make Meaningful Distinctions 20
Use Pronounceable Names 21
Use Searchable Names 22
Avoid Encodings 23
Avoid Mental Mapping 25
Class Names 25
Method Names 25
Don’t Be Cute 26
Pick One Word per Concept 26
Don’t Pun 26
Use Solution Domain Names 27
Use Problem Domain Names 27
Add Meaningful Context 27
Don’t Add Gratuitous Context 29
Final Words 30
Chapter 3: Functions 31
Do One Thing 35
One Level of Abstraction per Function 36
Switch Statements 37
Use Descriptive Names 39
Function Arguments 40
Have No Side Effects 44
Command Query Separation 45
Prefer Exceptions to Returning Error Codes 46
Don’t Repeat Yourself 48
Structured Programming 48
How Do You Write Functions Like This? 49
Chapter 4: Comments 53
Comments Do Not Make Up for Bad Code 55
Explain Yourself in Code 55
Good Comments 55
Bad Comments 59
Chapter 5: Formatting 75
The Purpose of Formatting 76
Vertical Formatting 76
Horizontal Formatting 85
Team Rules 90
Uncle Bob’s Formatting Rules 90
Chapter 6: Objects and Data Structures 93
Data Abstraction 93
Data/Object Anti-Symmetry 95
The Law of Demeter 97
Data Transfer Objects 100
Chapter 7: Error Handling 103
Use Exceptions Rather Than Return Codes 104
Write Your Try-Catch-Finally Statement First 105
Use Unchecked Exceptions 106
Provide Context with Exceptions 107
Define Exception Classes in Terms of a Caller’s Needs 107
Define the Normal Flow 109
Don’t Return Null 110
Don’t Pass Null 111
Chapter 8: Boundaries 113
Using Third-Party Code 114
Exploring and Learning Boundaries 116
Learning log4j 116
Learning Tests Are Better Than Free 118
Using Code That Does Not Yet Exist 118
Clean Boundaries 120
Chapter 9: Unit Tests 121
The Three Laws of TDD 122
Keeping Tests Clean 123
Clean Tests 124
One Assert per Test 130
Chapter 10: Classes 135
Class Organization 136
Classes Should Be Small! 136
Organizing for Change 147
Chapter 11: Systems 153
How Would You Build a City? 154
Separate Constructing a System from Using It 154
Scaling Up 157
Java Proxies 161
Pure Java AOP Frameworks 163
AspectJ Aspects 166
Test Drive the System Architecture 166
Optimize Decision Making 167
Use Standards Wisely, When They Add Demonstrable Value 168
Systems Need Domain-Specific Languages 168
Chapter 12: Emergence 171
Getting Clean via Emergent Design 171
Simple Design Rule 1: Runs All the Tests 172
Simple Design Rules 2–4: Refactoring 172
No Duplication 173
Minimal Classes and Methods 176
Chapter 13: Concurrency 177
Why Concurrency? 178
Concurrency Defense Principles 180
Know Your Library 182
Know Your Execution Models 183
Beware Dependencies Between Synchronized Methods 185
Keep Synchronized Sections Small 185
Writing Correct Shut-Down Code Is Hard 186
Testing Threaded Code 186
Chapter 14: Successive Refinement 193
Args Implementation 194
Args: The Rough Draft 201
String Arguments 214
Chapter 15: JUnit Internals 251
The JUnit Framework 252
Chapter 16: Refactoring SerialDate 267
First, Make It Work 268
Then Make It Right 270
Chapter 17: Smells and Heuristics 285
Appendix A: Concurrency II 317
Client/Server Example 317
Possible Paths of Execution 321
Knowing Your Library 326
Dependencies Between Methods Can Break Concurrent Code 329
Increasing Throughput 333
Testing Multithreaded Code 339
Tool Support for Testing Thread-Based Code 342
Tutorial: Full Code Examples 343
Appendix B: org.jfree.date.SerialDate 349
Appendix C: Cross References of Heuristics 409
Which door represents your code? Which door represents your team or your company? Why are we in that room? Is this just a normal code review or have we found a stream of horrible problems shortly after going live? Are we debugging in a panic, poring over code that we thought worked? Are customers leaving in droves and managers breathing down our necks? How can we make sure we wind up behind the right door when the going gets tough? The answer is: craftsmanship.
There are two parts to learning craftsmanship: knowledge and work. You must gain the knowledge of principles, patterns, practices, and heuristics that a craftsman knows, and you must also grind that knowledge into your fingers, eyes, and gut by working hard and practicing.
I can teach you the physics of riding a bicycle. Indeed, the classical mathematics is relatively straightforward. Gravity, friction, angular momentum, center of mass, and so forth, can be demonstrated with less than a page full of equations. Given those formulae I could prove to you that bicycle riding is practical and give you all the knowledge you needed to make it work. And you'd still fall down the first time you climbed on that bike.
Coding is no different. We could write down all the 'feel good' principles of clean code and then trust you to do the work (in other words, let you fall down when you get on the bike), but then what kind of teachers would that make us, and what kind of student would that make you?
No. That's not the way this book is going to work.
Learning to write clean code is hard work. It requires more than just the knowledge of principles and patterns. You must sweat over it. You must practice it yourself, and watch yourself fail. You must watch others practice it and fail. You must see them stumble and retrace their steps. You must see them agonize over decisions and see the price they pay for making those decisions the wrong way.
Be prepared to work hard while reading this book. This is not a 'feel good' book that you can read on an airplane and finish before you land. This book will make you work, and work hard. What kind of work will you be doing? You'll be reading codelots of code. And you will be challenged to think about what's right about that code and what's wrong with it. You'll be asked to follow along as we take modules apart and put them back together again. This will take time and effort; but we think it will be worth it.
We have divided this book into three parts. The first several chapters describe the principles, patterns, and practices of writing clean code. There is quite a bit of code in these chapters, and they will be challenging to read. They'll prepare you for the second section to come. If you put the book down after reading the first section, good luck to you!
The second part of the book is the harder work. It consists of several case studies of ever-increasing complexity. Each case study is an exercise in cleaning up some codeof transforming code that has some problems into code that has fewer problems. The detail in this section is intense. You will have to flip back and forth between the narrative and the code listings. You will have to analyze and understand the code we are working with and walk through our reasoning for making each change we make. Set aside some time because this should take you days.
The third part of this book is the payoff. It is a single chapter containing a list of heuristics and smells gathered while creating the case studies. As we walked through and cleaned up the code in the case studies, we documented every reason for our actions as a heuristic or smell. We tried to understand our own reactions to the code we were reading and changing, and worked hard to capture why we felt what we felt and did what we did. The result is a knowledge base that desribes the way we think when we write, read, and clean code.
This knowledge base is of limited value if you don't do the work of carefully reading through the case studies in the second part of this book. In those case studies we have carefully annotated each change we made with forward references to the heuristics. These forward references appear in square brackets like this: H22. This lets you see the context in which those heuristics were applied and written! It is not the heuristics themselves that are so valuable, it is the relationship between those heuristics and the discrete decisions we made while cleaning up the code in the case studies.
To further help you with those relationships, we have placed a cross-reference at the end of the book that shows the page number for every forward reference. You can use it to look up each place where a certain heuristic was applied.
If you read the first and third sections and skip over the case studies, then you will have read yet another 'feel good' book about writing good software. But if you take the time to work through the case studies, following every tiny step, every minute decisionif you put yourself in our place, and force yourself to think along the same paths that we thought, then you will gain a much richer understanding of those principles, patterns, practices, and heuristics. They won't be 'feel good' knowledge any more. They'll have been ground into your gut, fingers, and heart. They'll have become part of you in the same way that a bicycle becomes an extension of your will when you have mastered how to ride it.
Most Helpful Customer Reviews
Great book, full of practical advice on techniques you can use at the level of individual functions to make code simpler to understand, easier to modify and maintain, and more reliable (because bugs have nowhere to hide). Example code is in Java, but is so straightforward and clean that any programmer should be able to understand. Probably only marginally useful for the new programmer who might still be learning the syntax and basic techniques of programming. Essential reading for a professional programmer.
A really great book to read. I think it's a must read for software developers, for beginners as well as professionals. It helps a lot with the implementation details of software development. It answers questions for you like:- When to write documentation?- What are the steps to take when refactoring?- How important is naming in my code.The concepts are very well written. After reading the book and recommending it to my co-workers, it really felt the quality of our code was improving by applying the priciples written in the book. Like I said: a must read for every team involved in creating software!
Excellent book about software development. A must read for everyone involved in development Java, C# or a similar language.Robert Martin explains why good coding practices are important, and how you can accomplish to code properly.
I don't tend to read a ton of books that pertain to my profession. In the software development field, technology moves along at such a fast pace that most tech books are outdated almost before they hit the shelves. The books I do enjoy in this genre are those that espouse some theory, techniques or ideas that are timeless and are applicable despite the technology. This is one of those such books. Every developer should read this one. Most of the concepts inside are common sense ideas, but ones that you may not realize are important. Definitely one that will gain a space on my shelf and which I shall refer back to from time to time as a refresher or to clarify some position. Great stuff, if you develop software, buy this book.
I would recommend this as a must read for Java programmers, along with Joshua Bloch´s 'Effective Java'.Programmers using other languagens should also read, since the concepts listed in this book apply to a broad range of platforms.
This is a very good book on a topic that doesn't get enough coverage. After 30+ years I've seen too much code written for the moment - "quick and dirty". By that I mean its done fast and focused on the task at hand. It compiles, it tests clean ... on to the next task. This book provides some solid practices for writing clean code, and if followed should instill some habits that will help your future self pickup and run with the code you are writing today. I don't agree with all of his suggestions - I know I comment more then he would like - but the point is you need to think about writing clean code! If you do that you will spend A LOT LESS time maintaining the code going forward. I strongly recommend it to every new and old programmer. 30+ years and I'm still learning.