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