Clean Code

Robert C. Martin SeriesThe 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 arehighly experienced craftsmen and professionals dedicated to writing about whatactually works in practice, as opposed to what might work in theory. You will readabout what the author has done, not what he thinks you should do. If the book isabout programming, there will be lots of code. If the book is about managing, therewill 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 guidingprofessionals to become true craftsman.Managing Agile ProjectsSanjiv AugustineAgile Estimating and PlanningMike CohnWorking Effectively with Legacy CodeMichael C. FeathersAgile Java : Crafting Code with Test-Driven DevelopmentJeff LangrAgile Principles, Patterns, and Practices in C#Robert C. Martin and Micah MartinAgile Software Development: Principles, Patterns, and PracticesRobert C. MartinClean Code: A Handbook of Agile Software CraftsmanshipRobert C. MartinUML For Java ProgrammersRobert C. MartinFit for Developing Software: Framework for Integrated TestsRick Mugridge and Ward CunninghamAgile Software Development with SCRUMKen Schwaber and Mike BeedleExtreme Software Engineering: A Hands on ApproachDaniel H. Steinberg and Daniel W. PalmerFor more information, visit

Clean CodeA Handbook of AgileSoftware CraftsmanshipThe Object Mentors:Robert C. MartinMichael C. Feathers Timothy R. OttingerJeffrey J. Langr Brett L. SchuchertJames W. Grenning Kevin Dean WamplerObject 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 FranciscoNew York Toronto Montreal London Munich Paris MadridCapetown Sydney Tokyo Singapore Mexico City

Many of the designations used by manufacturers and sellers to distinguish their products are claimed astrademarks. 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 orimplied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumedfor incidental or consequential damages in connection with or arising out of the use of the information orprograms contained herein.The publisher offers excellent discounts on this book when ordered in quantity for bulk purchases orspecial sales, which may include electronic versions and/or custom covers and content particular to yourbusiness, training goals, marketing focus, and branding interests. For more information, please contact:U.S. Corporate and Government Sales(800) [email protected] sales outside the United States please contact:International [email protected] bibliographical references and index.ISBN 0-13-235088-2 (pbk. : alk. paper)1. Agile software development. 2. Computer software—Reliability. I. Title.QA76.76.D47M3652 2008005.1—dc222008024750Copyright 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 aretrieval system, or transmission in any form or by any means, electronic, mechanical, photocopying,recording, or likewise. For information regarding permissions, write to:Pearson Education, IncRights and Contracts Department501 Boylston Street, Suite 900Boston, MA 02116Fax: (617) 671-3447ISBN-13: 978-0-13-235088-4ISBN-10:0-13-235088-2Text 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

ContentsForeword . xixIntroduction .xxvOn the Cover. xxixChapter 1: Clean Code.1There Will Be Code .2Bad Code.3The Total Cost of Owning a Mess .4The Grand Redesign in the Sky.5Attitude.5The Primal Conundrum.6The Art of Clean Code?.6What Is Clean Code?.7Schools of Thought .12We Are Authors.13The Boy Scout Rule .14Prequel and Principles.15Conclusion.15Bibliography.15Chapter 2: Meaningful Names .17Introduction .17Use Intention-Revealing Names .18Avoid Disinformation .19Make Meaningful Distinctions .20Use Pronounceable Names.21Use Searchable Names .22vii

viiiContentsAvoid Encodings .23Hungarian Notation .23Member Prefixes.24Interfaces and Implementations .24Avoid Mental Mapping .25Class Names .25Method Names.25Don’t Be Cute .26Pick One Word per Concept.26Don’t Pun .26Use Solution Domain Names .27Use Problem Domain Names.27Add Meaningful Context .27Don’t Add Gratuitous Context .29Final Words .30Chapter 3: Functions .31Small!.34Blocks and Indenting.35Do One Thing.35Sections within Functions .36One Level of Abstraction per Function .36Reading Code from Top to Bottom: The Stepdown Rule.37Switch Statements .37Use Descriptive Names.39Function Arguments.40Common Monadic Forms.41Flag Arguments .41Dyadic Functions.42Triads.42Argument Objects.43Argument Lists .43Verbs and Keywords.43Have No Side Effects .44Output Arguments .45Command Query Separation .45

ContentsixPrefer Exceptions to Returning Error Codes .46Extract Try/Catch Blocks .46Error Handling Is One Thing.47The Dependency Magnet .47Don’t Repeat Yourself .48Structured Programming .48How Do You Write Functions Like This? .49Conclusion.49SetupTeardownIncluder .50Bibliography.52Chapter 4: Comments .53Comments Do Not Make Up for Bad Code.55Explain Yourself in Code .55Good Comments.55Legal Comments.55Informative Comments.56Explanation of Intent.56Clarification.57Warning of Consequences .58TODO Comments.58Amplification.59Javadocs in Public APIs.59Bad Comments .59Mumbling .59Redundant Comments .60Misleading Comments.63Mandated Comments.63Journal Comments.63Noise Comments .64Scary Noise .66Don’t Use a Comment When You Can Use aFunction or a Variable.67Position Markers.67Closing Brace Comments.67Attributions and Bylines.68

xContentsCommented-Out Code.68HTML Comments .69Nonlocal Information .69Too Much Information .70Inobvious Connection.70Function Headers.70Javadocs in Nonpublic Code .71Example.71Bibliography.74Chapter 5: Formatting .75The Purpose of Formatting .76Vertical Formatting .76The Newspaper Metaphor .77Vertical Openness Between Concepts .78Vertical Density .79Vertical Distance .80Vertical Ordering .84Horizontal Formatting.85Horizontal Openness and Density .86Horizontal Alignment.87Indentation.88Dummy Scopes.90Team Rules.90Uncle Bob’s Formatting Rules.90Chapter 6: Objects and Data Structures .93Data Abstraction.93Data/Object Anti-Symmetry .95The Law of Demeter.97Train Wrecks .98Hybrids .99Hiding Structure .99Data Transfer Objects.100Active Record.101Conclusion.101Bibliography.101

ContentsxiChapter 7: Error Handling .103Use Exceptions Rather Than Return Codes .104Write Your Try-Catch-Finally Statement First .105Use Unchecked Exceptions .106Provide Context with Exceptions.107Define Exception Classes in Terms of a Caller’s Needs.107Define the Normal Flow .109Don’t Return Null.110Don’t Pass Null .111Conclusion.112Bibliography.112Chapter 8: Boundaries .113Using Third-Party Code.114Exploring and Learning Boundaries.116Learning log4j .116Learning Tests Are Better Than Free.118Using Code That Does Not Yet Exist.118Clean Boundaries .120Bibliography.120Chapter 9: Unit Tests .121The Three Laws of TDD .122Keeping Tests Clean .123Tests Enable the -ilities.124Clean Tests .124Domain-Specific Testing Language.127A Dual Standard .127One Assert per Test .130Single Concept per Test pter 10: Classes .135Class Organization .136Encapsulation .136

xiiContentsClasses Should Be Small!.136The Single Responsibility Principle.138Cohesion.140Maintaining Cohesion Results in Many Small Classes.141Organizing for Change .147Isolating from Change.149Bibliography.151Chapter 11: Systems .153How Would You Build a City? .154Separate Constructing a System from Using It .154Separation of Main .155Factories .155Dependency Injection.157Scaling Up .157Cross-Cutting Concerns .160Java Proxies.161Pure Java AOP Frameworks.163AspectJ Aspects .166Test Drive the System Architecture.166Optimize Decision Making .167Use Standards Wisely, When They Add Demonstrable Value.168Systems Need Domain-Specific Languages.168Conclusion.169Bibliography.169Chapter 12: Emergence .171Getting Clean via Emergent Design .171Simple Design Rule 1: Runs All the Tests.172Simple Design Rules 2–4: Refactoring .172No Duplication.173Expressive.175Minimal Classes and Methods .176Conclusion.176Bibliography.176Chapter 13: Concurrency .177Why Concurrency? .178Myths and Misconceptions.179

ContentsxiiiChallenges .180Concurrency Defense Principles.180Single Responsibility Principle .181Corollary: Limit the Scope of Data .181Corollary: Use Copies of Data .181Corollary: Threads Should Be as Independent as Possible .182Know Your Library .182Thread-Safe Collections.182Know Your Execution Models .183Producer-Consumer.184Readers-Writers.184Dining Philosophers .184Beware Dependencies Between Synchronized Methods .185Keep Synchronized Sections Small.185Writing Correct Shut-Down Code Is Hard.186Testing Threaded Code .186Treat Spurious Failures as Candidate Threading Issues .187Get Your Nonthreaded Code Working First.187Make Your Threaded Code Pluggable .187Make Your Threaded Code Tunable.187Run with More Threads Than Processors.188Run on Different Platforms .188Instrument Your Code to Try and Force Failures.188Hand-Coded .189Automated .189Conclusion.190Bibliography.191Chapter 14: Successive Refinement .193Args Implementation .194How Did I Do This? .200Args: The Rough Draft .201So I Stopped .212On Incrementalism .212String Arguments .214Conclusion.250

xivContentsChapter 15: JUnit Internals .251The JUnit Framework.252Conclusion.265Chapter 16: Refactoring SerialDate .267First, Make It Work.268Then Make It Right.270Conclusion.284Bibliography.284Chapter 17: Smells and Heuristics .285Comments .286C1: Inappropriate Information.286C2: Obsolete Comment.286C3: Redundant Comment .286C4: Poorly Written Comment.287C5: Commented-Out Code .287Environment .287E1: Build Requires More Than One Step.287E2: Tests Require More Than One Step .287Functions.288F1: Too Many Arguments.288F2: Output Arguments .288F3: Flag Arguments .288F4: Dead Function .288General .288G1: Multiple Languages in One Source File.288G2: Obvious Behavior Is Unimplemented.288G3: Incorrect Behavior at the Boundaries .289G4: Overridden Safeties .289G5: Duplication.289G6: Code at Wrong Level of Abstraction.290G7: Base Classes Depending on Their Derivatives .291G8: Too Much Information .291G9: Dead Code.292G10: Vertical Separation .292G11: Inconsistency .292G12: Clutter.293

ContentsxvG13: Artificial Coupling .293G14: Feature Envy.293G15: Selector Arguments.294G16: Obscured Intent .295G17: Misplaced Responsibility.295G18: Inap

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