{"title": "Clean Code", "subtitle": "A Handbook of Agile Software Craftsmanship", "publish_date": "July 2008", "publishers": ["Prentice Hall"], "source_records": ["ia:cleancodehandboo00mart_668", "bwb:9780132350884", "marc:marc_loc_2016/BooksAll.2016.part35.utf8:123153805:1131", "ia:cleancodehandboo0000unse", "idb:9780132350884"], "covers": [15126503, 15106900, 15096391, 14840846, 8085499], "type": {"key": "/type/edition"}, "key": "/books/OL26222911M", "works": [{"key": "/works/OL17618370W"}], "identifiers": {}, "languages": [{"key": "/languages/eng"}], "physical_format": "Taschenbuch", "number_of_pages": 431, "table_of_contents": [{"level": 0, "title": "Foreword", "pagenum": "xix", "type": {"key": "/type/toc_item"}}, {"level": 0, "title": "Introduction", "pagenum": "xxv", "type": {"key": "/type/toc_item"}}, {"level": 0, "title": "On the Cover", "pagenum": "xxix", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 1", "title": "Clean Code", "pagenum": "1", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "There Will Be Code", "pagenum": "2", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bad Code", "pagenum": "3", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "The Total Cost of Owning a Mess", "pagenum": "4", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "The Grand Redesign in the Sky", "pagenum": "5", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Attitude", "pagenum": "5", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "The Primal Conundrum", "pagenum": "6", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "The Art of Clean Code?", "pagenum": "6", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "What Is Clean Code?", "pagenum": "7", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Schools of Thought", "pagenum": "12", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "We Are Authors", "pagenum": "13", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "The Boy Scout Rule", "pagenum": "14", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Prequel and Principles", "pagenum": "15", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "15", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "15", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 2", "title": "Meaningful Names", "pagenum": "17", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "A Introduction", "pagenum": "17", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Use Intention-Revealing Names", "pagenum": "18", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Avoid Disinformation", "pagenum": "19", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Make Meaningful Distinctions", "pagenum": "20", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Use Pronounceable Names", "pagenum": "21", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Use Searchable Names", "pagenum": "22", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Avoid Encodings", "pagenum": "23", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Hungarian Notation", "pagenum": "23", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Member Prefixes", "pagenum": "24", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Interfaces and Implementations", "pagenum": "24", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Avoid Mental Mapping", "pagenum": "25", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Class Names", "pagenum": "25", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Method Names", "pagenum": "25", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Don't Be Cute", "pagenum": "26", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Pick One Word per Concept", "pagenum": "26", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Don't Pun", "pagenum": "26", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Use Solution Domain Names", "pagenum": "27", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Use Problem Domain Names", "pagenum": "27", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Add Meaningful Context", "pagenum": "27", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Don't Add Gratuitous Context", "pagenum": "29", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Final Words", "pagenum": "30", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 3", "title": "Functions", "pagenum": "31", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Small!", "pagenum": "34", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Blocks and Indenting", "pagenum": "35", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Do One Thing", "pagenum": "35", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Sections within Functions", "pagenum": "36", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "One Level of Abstraction per Function", "pagenum": "36", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Reading Code from Top to Bottom: The Stepdown Rule", "pagenum": "37", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Switch Statements", "pagenum": "37", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Use Descriptive Names", "pagenum": "39", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Function Arguments", "pagenum": "40", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Common Monadic Forms", "pagenum": "41", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Flag Arguments", "pagenum": "41", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Dyadic Functions", "pagenum": "42", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Triads", "pagenum": "42", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Argument Objects", "pagenum": "43", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Argument Lists", "pagenum": "43", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Verbs and Keywords", "pagenum": "43", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Have No Side Effects", "pagenum": "44", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Output Arguments", "pagenum": "45", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Command Query Separation", "pagenum": "45", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Prefer Exceptions to Returning Error Codes", "pagenum": "46", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Extract Try/Catch Blocks", "pagenum": "46", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Error Handling Is One Thing", "pagenum": "47", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "The Error.java Dependency Magnet", "pagenum": "47", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Don't Repeat Yourself", "pagenum": "48", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Structured Programming", "pagenum": "48", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "How Do You Write Functions Like This?", "pagenum": "49", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "49", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "SetupTeardownIncluder", "pagenum": "50", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "52", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 4", "title": "Comments", "pagenum": "53", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Comments Do Not Make Up for Bad Code", "pagenum": "55", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Explain Yourself in Code", "pagenum": "55", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Good Comments", "pagenum": "55", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Legal Comments", "pagenum": "55", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Informative Comments", "pagenum": "56", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Explanation of Intent", "pagenum": "56", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Clarification", "pagenum": "57", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Warning of Consequences", "pagenum": "58", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "TODO Comments", "pagenum": "58", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Amplification", "pagenum": "59", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Javadocs in Public APIs", "pagenum": "59", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bad Comments", "pagenum": "59", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Mumbling", "pagenum": "59", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Redundant Comments", "pagenum": "60", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Misleading Comments", "pagenum": "63", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Mandated Comments", "pagenum": "63", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Journal Comments", "pagenum": "63", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Noise Comments", "pagenum": "64", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Scary Noise", "pagenum": "66", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Don't Use a Comment When You Can Use a Function or a Variable", "pagenum": "67", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Position Markers", "pagenum": "67", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Closing Brace Comments", "pagenum": "67", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Attributions and Bylines", "pagenum": "68", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Commented-Out Code", "pagenum": "68", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "HTML Comments", "pagenum": "69", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Nonlocal Information", "pagenum": "69", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Too Much Information", "pagenum": "70", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Inobvious Connection", "pagenum": "70", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Function Headers", "pagenum": "70", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Javadocs in Nonpublic Code", "pagenum": "71", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Example", "pagenum": "71", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "74", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 5", "title": "Formatting", "pagenum": "75", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "The Purpose of Formatting", "pagenum": "76", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Vertical Formatting", "pagenum": "76", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "The Newspaper Metaphor", "pagenum": "77", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Vertical Openness Between Concepts", "pagenum": "78", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Vertical Density", "pagenum": "79", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Vertical Distance", "pagenum": "80", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Vertical Ordering", "pagenum": "84", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Horizontal Formatting", "pagenum": "85", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Horizontal Openness and Density", "pagenum": "86", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Horizontal Alignment", "pagenum": "87", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Indentation", "pagenum": "88", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Dummy Scopes", "pagenum": "90", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Team Rules", "pagenum": "90", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Uncle Bob's Formatting Rules", "pagenum": "90", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 6", "title": "Objects and Data Structures", "pagenum": "93", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Data Abstraction", "pagenum": "93", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Data/Object Anti-Symmetry", "pagenum": "95", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "The Law of Demeter", "pagenum": "97", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Train Wrecks", "pagenum": "98", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Hybrids", "pagenum": "99", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Hiding Structure", "pagenum": "99", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Data Transfer Objects", "pagenum": "100", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Active Record", "pagenum": "101", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "101", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "101", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 7", "title": "Error Handling", "pagenum": "103", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Use Exceptions Rather Than Return Codes", "pagenum": "104", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Write Your Try-Catch-Finally Statement First", "pagenum": "105", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Use Unchecked Exceptions", "pagenum": "106", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Provide Context with Exceptions", "pagenum": "107", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Define Exception Classes in Terms of a Caller's Needs", "pagenum": "107", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Define the Normal Flow", "pagenum": "109", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Don't Return Null", "pagenum": "110", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Don't Pass Null", "pagenum": "111", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "112", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "112", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 8", "title": "Boundaries", "pagenum": "113", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Using Third-Party Code", "pagenum": "114", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Exploring and Learning Boundaries", "pagenum": "116", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Learning log4j", "pagenum": "116", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Learning Tests Are Better Than Free", "pagenum": "118", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Using Code That Does Not Yet Exist", "pagenum": "118", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Clean Boundaries", "pagenum": "120", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "120", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 9", "title": "Unit Tests", "pagenum": "121", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "The Three Laws of TDD", "pagenum": "122", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Keeping Tests Clean", "pagenum": "123", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Tests Enable the -ilities", "pagenum": "124", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Clean Tests", "pagenum": "124", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Domain-Specific Testing Language", "pagenum": "127", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "A Dual Standard", "pagenum": "127", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "One Assert per Test", "pagenum": "130", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Single Concept per Test", "pagenum": "131", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "F.I.R.S.T.", "pagenum": "132", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "133", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "133", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 10", "title": "Classes", "pagenum": "135", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Class Organization", "pagenum": "136", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Encapsulation", "pagenum": "136", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Classes Should Be Small!", "pagenum": "138", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "The Single Responsibility Principle", "pagenum": "138", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Cohesion", "pagenum": "140", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Maintaining Cohesion Results in Many Small Classes", "pagenum": "141", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Organizing for Change", "pagenum": "147", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Isolating from Change", "pagenum": "149", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "151", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 11", "title": "Systems", "pagenum": "153", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "How Would You Build a City?", "pagenum": "154", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Separate Constructing a System from Using It", "pagenum": "154", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Separation of Main", "pagenum": "155", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Factories", "pagenum": "155", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Dependency Injection", "pagenum": "157", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Scaling Up", "pagenum": "157", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Cross-Cutting Concerns", "pagenum": "160", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Java Proxies", "pagenum": "161", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Pure Java AOP Frameworks", "pagenum": "163", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "AspectJ Aspects", "pagenum": "166", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Test Drive the System Architecture", "pagenum": "166", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Optimize Decision Making", "pagenum": "167", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Use Standards Wisely, When They Add Demonstrable Value", "pagenum": "168", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Systems Need Domain-Specific Languages", "pagenum": "168", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "169", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "169", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 12", "title": "Emergence", "pagenum": "171", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Getting Clean via Emergent Design", "pagenum": "171", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Simple Design Rule 1: Runs All the Tests", "pagenum": "172", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Simple Design Rules 2-4: Refactoring", "pagenum": "172", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "No Duplication", "pagenum": "173", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Expressive", "pagenum": "175", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Minimal Classes and Methods", "pagenum": "176", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "176", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "176", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 13", "title": "Concurrency", "pagenum": "177", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Why Concurrency?", "pagenum": "178", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Myths and Misconceptions", "pagenum": "179", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Challenges", "pagenum": "180", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Concurrency Defense Principles", "pagenum": "180", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Single Responsibility Principle", "pagenum": "181", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Corollary: Limit the Scope of Data", "pagenum": "181", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Corollary: Use Copies of Data", "pagenum": "181", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Corollary: Threads Should Be as Independent as Possible", "pagenum": "182", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Know Your Library", "pagenum": "182", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Thread-Safe Collections", "pagenum": "182", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Know Your Execution Models", "pagenum": "183", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Producer-Consumer", "pagenum": "184", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Readers-Writers", "pagenum": "184", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Dining Philosophers", "pagenum": "184", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Beware Dependencies Between Synchronized Methods", "pagenum": "185", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Keep Synchronized Sections Small", "pagenum": "185", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Writing Correct Shut-Down Code Is Hard", "pagenum": "186", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Testing Threaded Code", "pagenum": "186", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Treat Spurious Failures as Candidate Threading Issues", "pagenum": "187", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Get Your Nonthreaded Code Working First", "pagenum": "187", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Make Your Threaded Code Pluggable", "pagenum": "187", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Make Your Threaded Code Tunable", "pagenum": "187", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Run with More Threads Than Processors", "pagenum": "188", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Run on Different Platforms", "pagenum": "188", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Instrument Your Code to Try and Force Failures", "pagenum": "188", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Hand-Coded", "pagenum": "189", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Automated", "pagenum": "189", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "190", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "191", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 14", "title": "Successive Refinement", "pagenum": "193", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Args Implementation", "pagenum": "194", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "How Did I Do This?", "pagenum": "200", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Args: The Rough Draft", "pagenum": "201", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "So I Stopped", "pagenum": "212", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "On Incrementalism", "pagenum": "212", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "String Arguments", "pagenum": "214", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "250", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 15", "title": "JUnit Internals", "pagenum": "251", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "The JUnit Framework", "pagenum": "252", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "265", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 16", "title": "Refactoring SerialDate", "pagenum": "267", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "First, Make It Work", "pagenum": "268", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Then Make It Right", "pagenum": "270", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "284", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "284", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Chapter 17", "title": "Smells and Heuristics", "pagenum": "285", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Comments", "pagenum": "286", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "C1", "title": "Inappropriate Information", "pagenum": "286", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "C2", "title": "Obsolete Comment", "pagenum": "286", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "C3", "title": "Redundant Comment", "pagenum": "286", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "C4", "title": "Poorly Written Comment", "pagenum": "287", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "C5", "title": "Commented-Out Code", "pagenum": "287", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Environment", "pagenum": "287", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "E1", "title": "Build Requires More Than One Step", "pagenum": "287", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "E2", "title": "Tests Require More Than One Step", "pagenum": "287", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Functions", "pagenum": "288", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "F1", "title": "Too Many Arguments", "pagenum": "288", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "F2", "title": "Output Arguments", "pagenum": "288", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "F3", "title": "Flag Arguments", "pagenum": "288", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "F4", "title": "Dead Function", "pagenum": "288", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "General", "pagenum": "288", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G1", "title": "Multiple Languages in One Source File", "pagenum": "288", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G2", "title": "Obvious Behavior Is Unimplemented", "pagenum": "288", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G3", "title": "Incorrect Behavior at the Boundaries", "pagenum": "289", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G4", "title": "Overridden Safeties", "pagenum": "289", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G5", "title": "Duplication", "pagenum": "289", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G6", "title": "Code at Wrong Level of Abstraction", "pagenum": "290", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G7", "title": "Base Classes Depending on Their Derivatives", "pagenum": "291", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G8", "title": "Too Much Information", "pagenum": "291", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G9", "title": "Dead Code", "pagenum": "292", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G10", "title": "Vertical Separation", "pagenum": "292", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G11", "title": "Inconsistency", "pagenum": "292", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G12", "title": "Clutter", "pagenum": "293", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G13", "title": "Artificial Coupling", "pagenum": "293", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G14", "title": "Feature Envy", "pagenum": "293", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G15", "title": "Selector Arguments", "pagenum": "294", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G16", "title": "Obscured Intent", "pagenum": "295", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G17", "title": "Misplaced Responsibility", "pagenum": "295", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G18", "title": "Inappropriate Static", "pagenum": "296", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G19", "title": "Use Explanatory Variables", "pagenum": "296", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G20", "title": "Function Names Should Say What They Do", "pagenum": "297", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G21", "title": "Understand the Algorithm", "pagenum": "297", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G22", "title": "Make Logical Dependencies Physical", "pagenum": "298", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G23", "title": "Prefer Polymorphism to If/Else or Switch/Case", "pagenum": "299", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G24", "title": "Follow Standard Conventions", "pagenum": "299", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G25", "title": "Replace Magic Numbers with Named Constants", "pagenum": "300", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G26", "title": "Be Precise", "pagenum": "301", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G27", "title": "Structure over Convention", "pagenum": "301", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G28", "title": "Encapsulate Conditionals", "pagenum": "301", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G29", "title": "Avoid Negative Conditionals", "pagenum": "302", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G30", "title": "Functions Should Do One Thing", "pagenum": "302", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G31", "title": "Hidden Temporal Couplings", "pagenum": "302", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G32", "title": "Don't Be Arbitrary", "pagenum": "303", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G33", "title": "Encapsulate Boundary Conditions", "pagenum": "304", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G34", "title": "Functions Should Descend Only One Level of Abstraction", "pagenum": "304", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G35", "title": "Keep Configurable Data at High Levels", "pagenum": "306", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "G36", "title": "Avoid Transitive Navigation", "pagenum": "306", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Java", "pagenum": "307", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "J1", "title": "Avoid Long Import Lists by Using Wildcards", "pagenum": "307", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "J2", "title": "Don't Inherit Constants", "pagenum": "307", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "J3", "title": "Constants versus Enums", "pagenum": "308", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Names", "pagenum": "309", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "N1", "title": "Choose Descriptive Names", "pagenum": "309", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "N2", "title": "Choose Names at the Appropriate Level of Abstraction", "pagenum": "311", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "N3", "title": "Use Standard Nomenclature Where Possible", "pagenum": "311", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "N4", "title": "Unambiguous Names", "pagenum": "312", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "N5", "title": "Use Long Names for Long Scopes", "pagenum": "312", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "N6", "title": "Avoid Encodings", "pagenum": "312", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "N7", "title": "Names Should Describe Side-Effects", "pagenum": "313", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Tests", "pagenum": "313", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "T1", "title": "Insufficient Tests", "pagenum": "313", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "T2", "title": "Use a Coverage Tool!", "pagenum": "313", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "T3", "title": "Don't Skip Trivial Tests", "pagenum": "313", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "T4", "title": "An Ignored Test Is a Question About an Ambiguity", "pagenum": "313", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "T5", "title": "Test Boundary Conditions", "pagenum": "314", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "T6", "title": "Exhaustively Test Near Bugs", "pagenum": "314", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "T7", "title": "Patterns of Failure Are Revealing", "pagenum": "314", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "T8", "title": "Test Coverage Patterns Can Be Revealing", "pagenum": "314", "type": {"key": "/type/toc_item"}}, {"level": 2, "label": "T9", "title": "Tests Should Be Fast", "pagenum": "314", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "314", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Bibliography", "pagenum": "315", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Appendix A", "title": "Concurrency", "pagenum": "317", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Client/Server Example", "pagenum": "317", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "The Server", "pagenum": "317", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Adding Threading", "pagenum": "319", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Server Observations", "pagenum": "319", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Conclusion", "pagenum": "321", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Possible Paths of Execution", "pagenum": "321", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Number of Paths", "pagenum": "322", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Digging Deeper", "pagenum": "323", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Conclusion", "pagenum": "326", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Knowing Your Library", "pagenum": "326", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Executor Framework", "pagenum": "326", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Nonblocking Solutions", "pagenum": "327", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Nonthread-Safe Classes", "pagenum": "328", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Dependencies Between Methods Can Break Concurrent Code", "pagenum": "329", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Tolerate the Failure", "pagenum": "330", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Client-Based Locking", "pagenum": "330", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Server-Based Locking", "pagenum": "332", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Increasing Throughput", "pagenum": "333", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Single-Thread Calculation of Throughput", "pagenum": "334", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Multithread Calculation of Throughput", "pagenum": "335", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Deadlock", "pagenum": "335", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Mutual Exclusion", "pagenum": "336", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Lock & Wait", "pagenum": "337", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "No Preemption", "pagenum": "337", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Circular Wait", "pagenum": "337", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Breaking Mutual Exclusion", "pagenum": "337", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Breaking Lock & Wait", "pagenum": "338", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Breaking Preemption", "pagenum": "338", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Breaking Circular Wait", "pagenum": "338", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Testing Multithreaded Code", "pagenum": "339", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Tool Support for Testing Thread-Based Code", "pagenum": "342", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Conclusion", "pagenum": "342", "type": {"key": "/type/toc_item"}}, {"level": 1, "title": "Tutorial: Full Code Examples", "pagenum": "343", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Client/Server Nonthreaded", "pagenum": "343", "type": {"key": "/type/toc_item"}}, {"level": 2, "title": "Client/Server Using Threads", "pagenum": "347", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Appendix B", "title": "org.jfree.date.SerialDate", "pagenum": "349", "type": {"key": "/type/toc_item"}}, {"level": 0, "label": "Appendix C", "title": "Cross References of Heuristics", "pagenum": "409", "type": {"key": "/type/toc_item"}}, {"level": 0, "title": "Epilogue", "pagenum": "411", "type": {"key": "/type/toc_item"}}, {"level": 0, "title": "Index", "pagenum": "413", "type": {"key": "/type/toc_item"}}], "ocaid": "cleancodehandboo0000unse", "isbn_10": ["0132350882"], "isbn_13": ["9780132350884"], "lccn": ["2008024750"], "lc_classifications": ["QA76.76.D47M3652", "QA76.76.D47 C583 2009"], "description": {"type": "/type/text", "value": "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.\r\n\r\nNoted 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.\r\n\r\nWhat 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.\r\n\r\nClean 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.\r\n\r\nReaders will come away from this book understanding\r\n\r\n - How to tell the difference between good and bad code\r\n - How to write good code and how to transform bad code into good code\r\n - How to create good names, good functions, good objects, and good classes\r\n - How to format code for maximum readability\r\n - How to implement complete error handling without obscuring code logic\r\n - How to unit test and practice test-driven development\r\n\r\nThis book is a must for any developer, software engineer, project manager, team lead, or systems analyst with an interest in producing better code."}, "latest_revision": 20, "revision": 20, "created": {"type": "/type/datetime", "value": "2017-02-09T02:17:10.400677"}, "last_modified": {"type": "/type/datetime", "value": "2025-09-26T13:52:58.784736"}}