Clean Code Cookbook: Recipes to Improve the Design and Quality of Your Code
Softwarequalität

Clean Code Cookbook: Recipes to Improve the Design and Quality of Your Code

Maximiliano Contieri, 2023

Inhaltsverzeichnis des Buches

  • Foreword
  • Preface
  • Who This Book Is For
  • How This Book Is Organized
  • What You Need to Use This Book
  • Access This Book in Digital Format
  • Conventions Used in This Book
  • Using Code Examples
  • O’Reilly Online Learning
  • How to Contact Us
  • Acknowledgments
  • 1. Clean Code
  • 1.1. What Is a Code Smell?
  • 1.2. What Is Refactoring?
  • 1.3. What Is a Recipe?
  • 1.4. Why Clean Code?
  • 1.5. Readability, Performance, or Both
  • 1.6. Software Types
  • 1.7. Machine-Generated Code
  • 1.8. Naming Considerations Throughout the Book
  • 1.9. Design Patterns
  • 1.10. Programming Language Paradigms
  • 1.11. Objects Versus Classes
  • 1.12. Changeability
  • 2. Setting Up the Axioms
  • 2.0. Introduction
  • 2.1. Why Is It a Model?
  • 2.2. Why Is It Abstract?
  • 2.3. Why Is It Programmable?
  • 2.4. Why Is It Partial?
  • 2.5. Why Is It Explanatory?
  • 2.6. Why Is It About Reality?
  • 2.7. Inferring the Rules
  • 2.8. The One and Only Software Design Principle
  • 3. Anemic Models
  • 3.0. Introduction
  • 3.1. Converting Anemic Objects to Rich Objects
  • 3.2. Identifying the Essence of Your Objects
  • 3.3. Removing Setters from Objects
  • 3.4. Removing Anemic Code Generators
  • 3.5. Removing Automatic Properties
  • 3.6. Removing DTOs
  • 3.7. Completing Empty Constructors
  • 3.8. Removing Getters
  • 3.9. Preventing Object Orgy
  • 3.10. Removing Dynamic Properties
  • 4. Primitive Obsession
  • 4.0. Introduction
  • 4.1. Creating Small Objects
  • 4.2. Reifying Primitive Data
  • 4.3. Reifying Associative Arrays
  • 4.4. Removing String Abuses
  • 4.5. Reifying Timestamps
  • 4.6. Reifying Subsets as Objects
  • 4.7. Reifying String Validations
  • 4.8. Removing Unnecessary Properties
  • 4.9. Creating Date Intervals
  • 5. Mutability
  • 5.0. Introduction
  • 5.1. Changing var to const
  • 5.2. Declaring Variables to Be Variable
  • 5.3. Forbidding Changes in the Essence
  • 5.4. Avoiding Mutable const Arrays
  • 5.5. Removing Lazy Initialization
  • 5.6. Freezing Mutable Constants
  • 5.7. Removing Side Effects
  • 5.8. Preventing Hoisting
  • 6. Declarative Code
  • 6.0. Introduction
  • 6.1. Narrowing Reused Variables
  • 6.2. Removing Empty Lines
  • 6.3. Removing Versioned Methods
  • 6.4. Removing Double Negatives
  • 6.5. Changing Misplaced Responsibilities
  • 6.6. Replacing Explicit Iterations
  • 6.7. Documenting Design Decisions
  • 6.8. Replacing Magic Numbers with Constants
  • 6.9. Separating “What” and “How”
  • 6.10. Documenting Regular Expressions
  • 6.11. Rewriting Yoda Conditions
  • 6.12. Removing Comedian Methods
  • 6.13. Avoiding Callback Hell
  • 6.15. Avoiding Magic Corrections
  • 7. Naming
  • 7.0. Introduction
  • 7.1. Expanding Abbreviations
  • 7.2. Renaming and Breaking Helpers and Utils
  • 7.3. Renaming MyObjects
  • 7.4. Renaming Result Variables
  • 7.5. Renaming Variables Named After Types
  • 7.6. Renaming Long Names
  • 7.7. Renaming Abstract Names
  • 7.8. Correcting Spelling Mistakes
  • 7.9. Removing Class Names from Attributes
  • 7.10. Removing the First Letter from Classes and Interfaces
  • 7.11. Renaming Basic / Do Functions
  • 7.12. Converting Plural Classes to Singular
  • 7.13. Removing “Collection” from Names
  • 7.14. Removing “Impl” Prefix/Suffix from Class Names
  • 7.15. Renaming Arguments According to Role
  • 7.16. Removing Redundant Parameter Names
  • 7.17. Removing Gratuitous Context from Names
  • 7.18. Avoiding Data Naming
  • 8. Comments
  • 8.0. Introduction
  • 8.1. Removing Commented Code
  • 8.2. Removing Obsolete Comments
  • 8.3. Removing Logical Comments
  • 8.4. Removing Getter Comments
  • 8.5. Converting Comments to Function Names
  • 8.6. Removing Comments Inside Methods
  • 8.7. Replacing Comments with Tests
  • 9. Standards
  • 9.0. Introduction
  • 9.1. Following Code Standards
  • 9.2. Standardizing Indentations
  • 9.3. Unifying Case Conventions
  • 9.4. Writing Code in English
  • 9.5. Unifying Parameter Order
  • 9.6. Fixing Broken Windows
  • 10. Complexity
  • 10.0. Introduction
  • 10.1. Removing Repeated Code
  • 10.2. Removing Settings/Configs and Feature Toggles
  • 10.3. Changing State as Properties
  • 10.4. Removing Cleverness from Code
  • 10.5. Breaking Multiple Promises
  • 10.6. Breaking Long Chains of Collaborations
  • 10.7. Extracting a Method to an Object
  • 10.8. Looking After Array Constructors
  • 10.9. Removing Poltergeist Objects
  • 11. Bloaters
  • 11.0. Introduction
  • 11.1. Breaking Too Long Methods
  • 11.2. Reducing Excess Arguments
  • 11.3. Reducing Excess Variables
  • 11.4. Removing Excessive Parentheses
  • 11.5. Removing Excess Methods
  • 11.6. Breaking Too Many Attributes
  • 11.7. Reducing Import Lists
  • 11.8. Breaking “And” Functions
  • 11.9. Breaking Fat Interfaces
  • 12. YAGNI
  • 12.0. Introduction
  • 12.1. Removing Dead Code
  • 12.2. Using Code Instead of Diagrams
  • 12.3. Refactoring Classes with One Subclass
  • 12.4. Removing One-Use Interfaces
  • 12.5. Removing Design Pattern Abuses
  • 12.6. Replacing Business Collections
  • 13. Fail Fast
  • 13.0. Introduction
  • 13.1. Refactoring Reassignment of Variables
  • 13.2. Enforcing Preconditions
  • 13.3. Using Stricter Parameters
  • 13.4. Removing Default from Switches
  • 13.5. Avoiding Modifying Collections While Traversing
  • 13.6. Redefining Hash and Equality
  • 13.7. Refactoring Without Functional Changes
  • 14. Ifs
  • 14.0. Introduction
  • 14.1. Replacing Accidental Ifs with Polymorphism
  • 14.2. Renaming Flag Variables for Events
  • 14.3. Reifying Boolean Variables
  • 14.4. Replacing Switch/Case/Elseif Statements
  • 14.5. Replacing Hardcoded If Conditions with Collections
  • 14.6. Changing Boolean to Short-Circuit Conditions
  • 14.7. Adding Implicit Else
  • 14.8. Rewriting Conditional Arrow Code
  • 14.9. Avoiding Short-Circuit Hacks
  • 14.10. Rewriting Nested Arrow Code
  • 14.11. Preventing Return Boolean Values for Condition Checks
  • 14.12. Changing Comparison Against Booleans
  • 14.13. Extracting from Long Ternaries
  • 14.14. Converting Nonpolymorphic Functions to Polymorphic
  • 14.15. Changing Equal Comparison
  • 14.16. Reifying Hardcoded Business Conditions
  • 14.17. Removing Gratuitous Booleans
  • 14.18. Rewriting Nested Ternaries
  • 15. Null
  • 15.0. Introduction
  • 15.1. Creating Null Objects
  • 15.2. Removing Optional Chaining
  • 15.3. Converting Optional Attributes to a Collection
  • 15.4. Using Real Objects for Null
  • 15.5. Representing Unknown Locations Without Using Null
  • 16. Premature Optimization
  • 16.0. Introduction
  • 16.1. Avoiding IDs on Objects
  • 16.2. Removing Premature Optimization
  • 16.3. Removing Bitwise Premature Optimizations
  • 16.4. Reducing Overgeneralization
  • 16.5. Changing Structural Optimizations
  • 16.6. Removing Anchor Boats
  • 16.7. Extracting Caches from Domain Objects
  • 16.8. Removing Callback Events Based on Implementation
  • 16.9. Removing Queries from Constructors
  • 16.10. Removing Code from Destructors
  • 17. Coupling
  • 17.0. Introduction
  • 17.1. Making Hidden Assumptions Explicit
  • 17.2. Replacing Singletons
  • 17.3. Breaking God Objects
  • 17.4. Breaking Divergent Change
  • 17.5. Converting 9999 Special Flag Values to Normal
  • 17.6. Removing Shotgun Surgery
  • 17.7. Removing Optional Arguments
  • 17.8. Preventing Feature Envy
  • 17.9. Removing the Middleman
  • 17.10. Moving Default Arguments to the End
  • 17.11. Avoiding the Ripple Effect
  • 17.12. Removing Accidental Methods on Business Objects
  • 17.13. Removing Business Code from the User Interface
  • 17.14. Changing Coupling to Classes
  • 17.15. Refactoring Data Clumps
  • 17.16. Breaking Inappropriate Intimacy
  • 17.17. Converting Fungible Objects
  • 18. Globals
  • 18.0. Introduction
  • 18.1. Reifying Global Functions
  • 18.2. Reifying Static Functions
  • 18.3. Replacing GoTo with Structured Code
  • 18.4. Removing Global Classes
  • 18.5. Changing Global Date Creation
  • 19. Hierarchies
  • 19.0. Introduction
  • 19.1. Breaking Deep Inheritance
  • 19.2. Breaking Yo-Yo Hierarchies
  • 19.3. Breaking Subclassification for Code Reuse
  • 19.4. Replacing “is-a” Relationship with Behavior
  • 19.5. Removing Nested Classes
  • 19.6. Renaming Isolated Classes
  • 19.7. Making Concrete Classes Final
  • 19.8. Defining Class Inheritance Explicitly
  • 19.9. Migrating Empty Classes
  • 19.10. Delaying Premature Classification
  • 19.11. Removing Protected Attributes
  • 19.12. Completing Empty Implementations
  • 20. Testing
  • 20.0. Introduction
  • 20.1. Testing Private Methods
  • 20.2. Adding Descriptions to Assertions
  • 20.3. Migrating assertTrue to Specific Assertions
  • 20.4. Replacing Mocks with Real Objects
  • 20.5. Refining Generic Assertions
  • 20.6. Removing Flaky Tests
  • 20.7. Changing Float Number Assertions
  • 20.8. Changing Test Data to Realistic Data
  • 20.9. Protecting Tests Violating Encapsulation
  • 20.10. Removing Irrelevant Test Information
  • 20.11. Adding Coverage for Every Merge Request
  • 20.12. Rewriting Tests Depending on Dates
  • 20.13. Learning a New Programming Language
  • 21. Technical Debt
  • 21.0. Introduction
  • 21.1. Removing Production-Dependent Code
  • 21.2. Removing Defect Trackers
  • 21.3. Removing Warning/Strict Off
  • 21.4. Preventing and Removing ToDos and FixMes
  • 22. Exceptions
  • 22.0. Introduction
  • 22.1. Removing Empty Exception Blocks
  • 22.2. Removing Unnecessary Exceptions
  • 22.3. Rewriting Exceptions for Expected Cases
  • 22.4. Rewriting Nested Try/Catches
  • 22.5. Replacing Return Codes with Exceptions
  • 22.6. Rewriting Exception Arrow Code
  • 22.7. Hiding Low-Level Errors from End Users
  • 22.8. Narrowing Exception Tries
  • 23. Metaprogramming
  • 23.0. Introduction
  • 23.1. Removing Metaprogramming Usage
  • 23.2. Reifying Anonymous Functions
  • 23.3. Removing Preprocessors
  • 23.4. Removing Dynamic Methods
  • 24. Types
  • 24.0. Introduction
  • 24.1. Removing Type Checking
  • 24.2. Dealing with Truthy Values
  • 24.3. Changing Float Numbers to Decimals
  • 25. Security
  • 25.0. Introduction
  • 25.1. Sanitizing Inputs
  • 25.2. Changing Sequential IDs
  • 25.3. Removing Package Dependencies
  • 25.4. Replacing Evil Regular Expressions
  • 25.5. Protecting Object Deserialization
  • Glossary of Terms
  • Index
  • About the Author