Clean Code Robert C. Martin Series The mission of this series is to improve the state of the art of software craftsmanship. The books in this series are technical, pragmatic, and substantial. The authors are highly experienced craftsmen and professionals dedicated to writing about what actually works in practice, as opposed to what might work in theory.
You will read about what the author has done, not what he thinks you should do. If the book is about programming, there will be lots of code. If the book is about managing, there will be lots of case studies from real projects. These are the books that all serious practitioners will have on their bookshelves.
These are the books that will be remembered for making a difference and for guiding professionals to become true craftsman. Managing Agile Projects Sanjiv Augustine Agile Estimating and Planning Mike Cohn Working Effectively with Legacy Code Michael C. Feathers Agile Java™: Crafting Code with Test-Driven Development Jeff Langr Agile Principles, Patterns, and Practices in C# Robert C. Martin and Micah Martin Agile Software Development: Principles, Patterns, and Practices Robert C.
Martin Clean Code: A Handbook of Agile Software Craftsmanship Robert C. Martin UML For Java™ Programmers Robert C. Martin Fit for Developing Software: Framework for Integrated Tests Rick Mugridge and Ward Cunningham Agile Software Development with SCRUM Ken Schwaber and Mike Beedle Extreme Software Engineering: A Hands on Approach Daniel H. Steinberg and Daniel W.
Palmer For more information, visit informit.com/martinseries Clean Code A Handbook of Agile Software Craftsmanship The Object Mentors: Robert C. Grenning Kevin Dean Wampler Object Mentor Inc. Writing clean code is what you must do in order to call yourself a professional. There is no reasonable excuse for doing anything less than your best.
Upper Saddle River, NJ • Boston • Indianapolis • San Francisco New York • Toronto • Montreal • London • Munich • Paris • Madrid Capetown • Sydney • Tokyo • Singapore • Mexico City Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and the publisher was aware of a trademark claim, the designations have been printed with initial capital letters or in all capitals. The authors and publisher have taken care in the preparation of this book, but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for incidental or consequential damages in connection with or arising out of the use of the information or programs contained herein.
The publisher offers excellent discounts on this book when ordered in quantity for bulk purchases or special sales, which may include electronic versions and/or custom covers and content particular to your business, training goals, marketing focus, and branding interests. For more information, please contact: U. Corporate and Government Sales (800) 382-3419 corpsales@pearsontechgroup.com For sales outside the United States please contact: International Sales international@pearsoned.com Includes bibliographical references and index. Agile software development.
Computer software—Reliability.1—dc22 2008024750 Copyright © 2009 Pearson Education, Inc. All rights reserved. Printed in the United States of America. This publication is protected by copyright, and permission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical, photocopying, recording, or likewise.
For information regarding permissions, write to: Pearson Education, Inc Rights and Contracts Department 501 Boylston Street, Suite 900 Boston, MA 02116 Fax: (617) 671-3447 ISBN-13: 978-0-13-235088-4 ISBN-10: 0-13-235088-2 Text printed in the United States on recycled paper at Courier in Stoughton, Massachusetts. First printing July, 2008 For Ann Marie: The ever enduring love of my life. This page intentionally left blank Contents Foreword .xxv On the Cover. xxix Chapter 1: Clean Code.1 There Will Be Code .3 The Total Cost of Owning a Mess .4 The Grand Redesign in the Sky.5 The Primal Conundrum.6 The Art of Clean Code?.6 What Is Clean Code?.7 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 .19 Make Meaningful Distinctions .20 Use Pronounceable Names.21 Use Searchable Names .22 vii viii Contents Avoid Encodings .23 Member Prefixes.24 Interfaces and Implementations .24 Avoid Mental Mapping .25 Don’t Be Cute .26 Pick One Word per Concept.26 Use Solution Domain Names .27 Use Problem Domain Names.27 Add Meaningful Context .27 Don’t Add Gratuitous Context .34 Blocks and Indenting.35 Do One Thing.35 Sections within Functions .36 One Level of Abstraction per Function .36 Reading Code from Top to Bottom: The Stepdown Rule.37 Use Descriptive Names.40 Common Monadic Forms.43 Verbs and Keywords.43 Have No Side Effects .45 Command Query Separation .45 Contents ix Prefer Exceptions to Returning Error Codes .46 Extract Try/Catch Blocks .46 Error Handling Is One Thing.java Dependency Magnet .47 Don’t Repeat Yourself .48 How Do You Write Functions Like This? .53 Comments Do Not Make Up for Bad Code.55 Explain Yourself in Code .56 Explanation of Intent.57 Warning of Consequences .59 Javadocs in Public APIs.66 Don’t Use a Comment When You Can Use a Function or a Variable.67 Closing Brace Comments.67 Attributions and Bylines.68 x Contents Commented-Out Code.69 Too Much Information .70 Javadocs in Nonpublic Code .75 The Purpose of Formatting .76 The Newspaper Metaphor .77 Vertical Openness Between Concepts .85 Horizontal Openness and Density .90 Uncle Bob’s Formatting Rules.90 Chapter 6: Objects and Data Structures .93 Data/Object Anti-Symmetry .95 The Law of Demeter.99 Data Transfer Objects.101 Contents xi 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 .113 Using Third-Party Code.114 Exploring and Learning Boundaries.116 Learning Tests Are Better Than Free.118 Using Code That Does Not Yet Exist.120 Chapter 9: Unit Tests .121 The Three Laws of TDD .122 Keeping Tests Clean .123 Tests Enable the -ilities.124 Domain-Specific Testing Language.127 One Assert per Test .130 Single Concept per Test .136 xii Contents Classes Should Be Small!.136 The Single Responsibility Principle.140 Maintaining Cohesion Results in Many Small Classes.141 Organizing for Change .147 Isolating from Change.153 How Would You Build a City? .154 Separate Constructing a System from Using It .154 Separation of Main .157 Cross-Cutting Concerns .161 Pure Java AOP Frameworks.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.171 Getting Clean via Emergent Design .171 Simple Design Rule 1: Runs All the Tests.172 Simple Design Rules 2–4: Refactoring .175 Minimal Classes and Methods .178 Myths and Misconceptions.179 Contents xiii Challenges .180 Concurrency Defense Principles.180 Single Responsibility Principle .181 Corollary: Limit the Scope of Data .181 Corollary: Use Copies of Data .181 Corollary: Threads Should Be as Independent as Possible .182 Know Your Library .182 Thread-Safe Collections.182 Know Your Execution Models .184 Beware Dependencies Between Synchronized Methods .185 Keep Synchronized Sections Small.185 Writing Correct Shut-Down Code Is Hard.186 Testing Threaded Code .186 Treat Spurious Failures as Candidate Threading Issues .187 Get Your Nonthreaded Code Working First.187 Make Your Threaded Code Pluggable .187 Make Your Threaded Code Tunable.187 Run with More Threads Than Processors.188 Run on Different Platforms .188 Instrument Your Code to Try and Force Failures.191 Chapter 14: Successive Refinement .194 How Did I Do This? .200 Args: The Rough Draft .250 xiv Contents Chapter 15: JUnit Internals .251 The JUnit Framework.265 Chapter 16: Refactoring SerialDate .267 First, Make It Work.268 Then Make It Right.284 Chapter 17: Smells and Heuristics .286 C4: Poorly Written Comment.287 C5: Commented-Out Code .287 E1: Build Requires More Than One Step.287 E2: Tests Require More Than One Step .288 F1: Too Many Arguments.288 G1: Multiple Languages in One Source File.288 G2: Obvious Behavior Is Unimplemented.288 G3: Incorrect Behavior at the Boundaries .289 G6: Code at Wrong Level of Abstraction.290 G7: Base Classes Depending on Their Derivatives .291 G8: Too Much Information .293 Contents xv G13: Artificial Coupling .296 G19: Use Explanatory Variables .296 G20: Function Names Should Say What They Do .297 G21: Understand the Algorithm .297 G22: Make Logical Dependencies Physical.298 G23: Prefer Polymorphism to If/Else or Switch/Case .299 G24: Follow Standard Conventions.299 G25: Replace Magic Numbers with Named Constants .301 G27: Structure over Convention.301 G29: Avoid Negative Conditionals .302 G30: Functions Should Do One Thing .302 G31: Hidden Temporal Couplings.302 G32: Don’t Be Arbitrary .303 G33: Encapsulate Boundary Conditions.304 G34: Functions Should Descend Only One Level of Abstraction .304 G35: Keep Configurable Data at High Levels.306 G36: Avoid Transitive Navigation.307 J1: Avoid Long Import Lists by Using Wildcards.307 J2: Don’t Inherit Constants .307 J3: Constants versus Enums .309 N1: Choose Descriptive Names.309 N2: Choose Names at the Appropriate Level of Abstraction.311 N3: Use Standard Nomenclature Where Possible.312 N5: Use Long Names for Long Scopes.312 N7: Names Should Describe Side-Effects.313 xvi Contents Tests .313 T1: Insufficient Tests .313 T2: Use a Coverage Tool!.313 T3: Don’t Skip Trivial Tests .313 T4: An Ignored Test Is a Question about an Ambiguity .313 T5: Test Boundary Conditions.314 T6: Exhaustively Test Near Bugs.314 T7: Patterns of Failure Are Revealing .314 T8: Test Coverage Patterns Can Be Revealing .314 T9: Tests Should Be Fast.315 Appendix A: Concurrency II.317 Client/Server Example.321 Possible Paths of Execution .321 Number of Paths.326 Knowing Your Library.327 Nonthread-Safe Classes.328 Dependencies Between Methods Can Break Concurrent Code .329 Tolerate the Failure.330 Client-Based Locking.330 Server-Based Locking .333 Single-Thread Calculation of Throughput.334 Multithread Calculation of Throughput.337 Contents xvii No Preemption.337 Breaking Mutual Exclusion.337 Breaking Lock & Wait.338 Breaking Circular Wait.338 Testing Multithreaded Code.339 Tool Support for Testing Thread-Based Code .342 Tutorial: Full Code Examples .343 Client/Server Nonthreaded.343 Client/Server Using Threads .349 Appendix C: Cross References of Heuristics.413 This page intentionally left blank Foreword One of our favorite candies here in Denmark is Ga-Jol, whose strong licorice vapors are a perfect complement to our damp and often chilly weather.
Part of the charm of Ga-Jol to us Danes is the wise or witty sayings printed on the flap of every box top. I bought a two- pack of the delicacy this morning and found that it bore this old Danish saw: Ærlighed i små ting er ikke nogen lille ting. “Honesty in small things is not a small thing.” It was a good omen consistent with what I already wanted to say here. Small things matter.
This is a book about humble concerns whose value is nonetheless far from small. God is in the details, said the architect Ludwig mies van der Rohe. This quote recalls contemporary arguments about the role of architecture in software development, and par- ticularly in the Agile world. Bob and I occasionally find ourselves passionately engaged in this dialogue.
And yes, mies van der Rohe was attentive to utility and to the timeless forms of building that underlie great architecture. On the other hand, he also personally selected every doorknob for every house he designed. Why? Because small things matter. In our ongoing “debate” on TDD, Bob and I have discovered that we agree that soft- ware architecture has an important place in development, though we likely have different visions of exactly what that means.
Such quibbles are relatively unimportant, however, because we can accept for granted that responsible professionals give some time to think- ing and planning at the outset of a project. The late-1990s notions of design driven only by the tests and the code are long gone. Yet attentiveness to detail is an even more critical foundation of professionalism than is any grand vision. First, it is through practice in the small that professionals gain proficiency and trust for practice in the large.
Second, the smallest bit of sloppy construction, of the door that does not close tightly or the slightly crooked tile on the floor, or even the messy desk, completely dispels the charm of the larger whole. That is what clean code is about.