O'Reilly logo

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Clean Code

Book Description

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

  • This book is a must for any developer, software engineer, project manager, team lead, or systems analyst with an interest in producing better code.

    Table of Contents

    1. Title Page
    2. Copyright Page
    3. Contents
    4. Foreword
    5. Introduction
    6. On the Cover
    7. Chapter 1: Clean Code
      1. There Will Be Code
      2. Bad Code
      3. The Total Cost of Owning a Mess
      4. The Grand Redesign in the Sky
      5. Attitude
      6. The Primal Conundrum
      7. The Art of Clean Code?
      8. What Is Clean Code?
      9. Schools of Thought
      10. We Are Authors
      11. The Boy Scout Rule
      12. Prequel and Principles
      13. Conclusion
      14. Bibliography
    8. Chapter 2: Meaningful Names
      1. Introduction
      2. Use Intention-Revealing Names
      3. Avoid Disinformation
      4. Make Meaningful Distinctions
      5. Use Pronounceable Names
      6. Use Searchable Names
      7. Avoid Encodings
      8. Hungarian Notation
      9. Member Prefixes
      10. Interfaces and Implementations
      11. Avoid Mental Mapping
      12. Class Names
      13. Method Names
      14. Don’t Be Cute
      15. Pick One Word per Concept
      16. Don’t Pun
      17. Use Solution Domain Names
      18. Use Problem Domain Names
      19. Add Meaningful Context
      20. Don’t Add Gratuitous Context
      21. Final Words
    9. Chapter 3: Functions
      1. Small!
      2. Blocks and Indenting
      3. Do One Thing
      4. Sections within Functions
      5. One Level of Abstraction per Function
      6. Reading Code from Top to Bottom: The Stepdown Rule
      7. Switch Statements
      8. Use Descriptive Names
      9. Function Arguments
      10. Common Monadic Forms
      11. Flag Arguments
      12. Dyadic Functions
      13. Triads
      14. Argument Objects
      15. Argument Lists
      16. Verbs and Keywords
      17. Have No Side Effects
      18. Output Arguments
      19. Command Query Separation
      20. Prefer Exceptions to Returning Error Codes
      21. Extract Try/Catch Blocks
      22. Error Handling Is One Thing
      23. The Error.java Dependency Magnet
      24. Don’t Repeat Yourself
      25. Structured Programming
      26. How Do You Write Functions Like This?
      27. Conclusion
      28. SetupTeardownIncluder
      29. Bibliography
    10. Chapter 4: Comments
      1. Comments Do Not Make Up for Bad Code
      2. Explain Yourself in Code
      3. Good Comments
      4. Legal Comments
      5. Informative Comments
      6. Explanation of Intent
      7. Clarification
      8. Warning of Consequences
      9. TODO Comments
      10. Amplification
      11. Javadocs in Public APIs
      12. Bad Comments
      13. Mumbling
      14. Redundant Comments
      15. Misleading Comments
      16. Mandated Comments
      17. Journal Comments
      18. Noise Comments
      19. Scary Noise
      20. Don’t Use a Comment When You Can Use a Function or a Variable
      21. Position Markers
      22. Closing Brace Comments
      23. Attributions and Bylines
      24. Commented-Out Code
      25. HTML Comments
      26. Nonlocal Information
      27. Too Much Information
      28. Inobvious Connection
      29. Function Headers
      30. Javadocs in Nonpublic Code
      31. Example
      32. Bibliography
    11. Chapter 5: Formatting
      1. The Purpose of Formatting
      2. Vertical Formatting
      3. The Newspaper Metaphor
      4. Vertical Openness Between Concepts
      5. Vertical Density
      6. Vertical Distance
      7. Vertical Ordering
      8. Horizontal Formatting
      9. Horizontal Openness and Density
      10. Horizontal Alignment
      11. Indentation
      12. Dummy Scopes
      13. Team Rules
      14. Uncle Bob’s Formatting Rules
    12. Chapter 6: Objects and Data Structures
      1. Data Abstraction
      2. Data/Object Anti-Symmetry
      3. The Law of Demeter
      4. Train Wrecks
      5. Hybrids
      6. Hiding Structure
      7. Data Transfer Objects
      8. Active Record
      9. Conclusion
      10. Bibliography
    13. Chapter 7: Error Handling
      1. Use Exceptions Rather Than Return Codes
      2. Write Your Try-Catch-Finally Statement First
      3. Use Unchecked Exceptions
      4. Provide Context with Exceptions
      5. Define Exception Classes in Terms of a Caller’s Needs
      6. Define the Normal Flow
      7. Don’t Return Null
      8. Don’t Pass Null
      9. Conclusion
      10. Bibliography
    14. Chapter 8: Boundaries
      1. Using Third-Party Code
      2. Exploring and Learning Boundaries
      3. Learning log4j
      4. Learning Tests Are Better Than Free
      5. Using Code That Does Not Yet Exist
      6. Clean Boundaries
      7. Bibliography
    15. Chapter 9: Unit Tests
      1. The Three Laws of TDD
      2. Keeping Tests Clean
      3. Tests Enable the -ilities
      4. Clean Tests
      5. Domain-Specific Testing Language
      6. A Dual Standard
      7. One Assert per Test
      8. Single Concept per Test
      9. F.I.R.S.T.
      10. Conclusion
      11. Bibliography
    16. Chapter 10: Classes
      1. Class Organization
      2. Encapsulation
      3. Classes Should Be Small!
      4. The Single Responsibility Principle
      5. Cohesion
      6. Maintaining Cohesion Results in Many Small Classes
      7. Organizing for Change
      8. Isolating from Change
      9. Bibliography
    17. Chapter 11: Systems
      1. How Would You Build a City?
      2. Separate Constructing a System from Using It
      3. Separation of Main
      4. Factories
      5. Dependency Injection
      6. Scaling Up
      7. Cross-Cutting Concerns
      8. Java Proxies
      9. Pure Java AOP Frameworks
      10. AspectJ Aspects
      11. Test Drive the System Architecture
      12. Optimize Decision Making
      13. Use Standards Wisely, When They Add Demonstrable Value
      14. Systems Need Domain-Specific Languages
      15. Conclusion
      16. Bibliography
    18. Chapter 12: Emergence
      1. Getting Clean via Emergent Design
      2. Simple Design Rule 1: Runs All the Tests
      3. Simple Design Rules 2–4: Refactoring
      4. No Duplication
      5. Expressive
      6. Minimal Classes and Methods
      7. Conclusion
      8. Bibliography
    19. Chapter 13: Concurrency
      1. Why Concurrency?
      2. Myths and Misconceptions
      3. Challenges
      4. Concurrency Defense Principles
      5. Single Responsibility Principle
      6. Corollary: Limit the Scope of Data
      7. Corollary: Use Copies of Data
      8. Corollary: Threads Should Be as Independent as Possible
      9. Know Your Library
      10. Thread-Safe Collections
      11. Know Your Execution Models
      12. Producer-Consumer
      13. Readers-Writers
      14. Dining Philosophers
      15. Beware Dependencies Between Synchronized Methods
      16. Keep Synchronized Sections Small
      17. Writing Correct Shut-Down Code Is Hard
      18. Testing Threaded Code
      19. Treat Spurious Failures as Candidate Threading Issues
      20. Get Your Nonthreaded Code Working First
      21. Make Your Threaded Code Pluggable
      22. Make Your Threaded Code Tunable
      23. Run with More Threads Than Processors
      24. Run on Different Platforms
      25. Instrument Your Code to Try and Force Failures
      26. Hand-Coded
      27. Automated
      28. Conclusion
      29. Bibliography
    20. Chapter 14: Successive Refinement
      1. Args Implementation
      2. How Did I Do This?
      3. Args: The Rough Draft
      4. So I Stopped
      5. On Incrementalism
      6. String Arguments
      7. Conclusion
    21. Chapter 15: JUnit Internals
      1. The JUnit Framework
      2. Conclusion
    22. Chapter 16: Refactoring SerialDate
      1. First, Make It Work
      2. Then Make It Right
      3. Conclusion
      4. Bibliography
    23. Chapter 17: Smells and Heuristics
      1. Comments
      2. C1: Inappropriate Information
      3. C2: Obsolete Comment
      4. C3: Redundant Comment
      5. C4: Poorly Written Comment
      6. C5: Commented-Out Code
      7. Environment
      8. E1: Build Requires More Than One Step
      9. E2: Tests Require More Than One Step
      10. Functions
      11. F1: Too Many Arguments
      12. F2: Output Arguments
      13. F3: Flag Arguments
      14. F4: Dead Function
      15. General
      16. G1: Multiple Languages in One Source File
      17. G2: Obvious Behavior Is Unimplemented
      18. G3: Incorrect Behavior at the Boundaries
      19. G4: Overridden Safeties
      20. G5: Duplication
      21. G6: Code at Wrong Level of Abstraction
      22. G7: Base Classes Depending on Their Derivatives
      23. G8: Too Much Information
      24. G9: Dead Code
      25. G10: Vertical Separation
      26. G11: Inconsistency
      27. G12: Clutter
      28. G13: Artificial Coupling
      29. G14: Feature Envy
      30. G15: Selector Arguments
      31. G16: Obscured Intent
      32. G17: Misplaced Responsibility
      33. G18: Inappropriate Static
      34. G19: Use Explanatory Variables
      35. G20: Function Names Should Say What They Do
      36. G21: Understand the Algorithm
      37. G22: Make Logical Dependencies Physical
      38. G23: Prefer Polymorphism to If/Else or Switch/Case
      39. G24: Follow Standard Conventions
      40. G25: Replace Magic Numbers with Named Constants
      41. G26: Be Precise
      42. G27: Structure over Convention
      43. G28: Encapsulate Conditionals
      44. G29: Avoid Negative Conditionals
      45. G30: Functions Should Do One Thing
      46. G31: Hidden Temporal Couplings
      47. G32: Don’t Be Arbitrary
      48. G33: Encapsulate Boundary Conditions
      49. G34: Functions Should Descend Only One Level of Abstraction
      50. G35: Keep Configurable Data at High Levels
      51. G36: Avoid Transitive Navigation
      52. Java
      53. J1: Avoid Long Import Lists by Using Wildcards
      54. J2: Don’t Inherit Constants
      55. J3: Constants versus Enums
      56. Names
      57. N1: Choose Descriptive Names
      58. N2: Choose Names at the Appropriate Level of Abstraction
      59. N3: Use Standard Nomenclature Where Possible
      60. N4: Unambiguous Names
      61. N5: Use Long Names for Long Scopes
      62. N6: Avoid Encodings
      63. N7: Names Should Describe Side-Effects.
      64. Tests
      65. T1: Insufficient Tests
      66. T2: Use a Coverage Tool!
      67. T3: Don’t Skip Trivial Tests
      68. T4: An Ignored Test Is a Question about an Ambiguity
      69. T5: Test Boundary Conditions
      70. T6: Exhaustively Test Near Bugs
      71. T7: Patterns of Failure Are Revealing
      72. T8: Test Coverage Patterns Can Be Revealing
      73. T9: Tests Should Be Fast
      74. Conclusion
      75. Bibliography
    24. Appendix A: Concurrency II
      1. Client/Server Example
      2. The Server
      3. Adding Threading
      4. Server Observations
      5. Conclusion
      6. Possible Paths of Execution
      7. Number of Paths
      8. Digging Deeper
      9. Conclusion
      10. Knowing Your Library
      11. Executor Framework
      12. Nonblocking Solutions
      13. Nonthread-Safe Classes
      14. Dependencies Between Methods Can Break Concurrent Code
      15. Tolerate the Failure
      16. Client-Based Locking
      17. Server-Based Locking
      18. Increasing Throughput
      19. Single-Thread Calculation of Throughput
      20. Multithread Calculation of Throughput
      21. Deadlock
      22. Mutual Exclusion
      23. Lock & Wait
      24. No Preemption
      25. Circular Wait
      26. Breaking Mutual Exclusion
      27. Breaking Lock & Wait
      28. Breaking Preemption
      29. Breaking Circular Wait
      30. Testing Multithreaded Code
      31. Tool Support for Testing Thread-Based Code
      32. Conclusion
      33. Tutorial: Full Code Examples
      34. Client/Server Nonthreaded
      35. Client/Server Using Threads
    25. Appendix B: org.jfree.date.SerialDate
    26. Appendix C: Cross References of Heuristics
    27. Epilogue
    28. Index