Often, software engineers and architects work with large, complex code bases that they need to scale and maintain. With this cookbook, author Maximiliano Contieri takes you beyond the concept of clean code by showing you how to identify improvement opportunities and their impact on production code. When it comes to reliability and system evolution, these techniques provide benefits that pay off over time.
Using real life examples in JavaScript, PHP, Java, Python, and many other programming languages, this cookbook provides proven recipes to help you scale and maintain large systems. Every section covers fundamental concepts including readability, coupling, testability, and extensibility, as well as code smells—symptoms of a problem that requires special attention—and the recipes to address them.
As you proceed through this book, refactoring recipes and the variety of code smells increase in complexity. You will:
• Understand the benefits of clean code and learn how to detect code smells
• Learn refactoring techniques step by step
• Gain illustrative code examples in several modern programming languages
• Get a comprehensive catalog of common code smells, their impacts, and possible solutions
• Use code that's straight to the point, favoring readability and learning
Author(s): Maximiliano Contieri
Edition: 1
Publisher: O'Reilly Media
Year: 2023
Language: English
Commentary: Publisher's PDF | Published: September 2023 | Revision History: 2023-09-11: First Release
Pages: 428
City: Sebastopol, CA
Tags: Software Engineering; Security; Design Patterns; Best Practices; Refactoring; Testing; Complexity; Metaprogramming; Technical Debt; Comments; Exception Handling; Abstraction; Coupling; Naming; Clean Code; YAGNI; Declarative Programming; Code Smell; Mutability; Premature Optimization
Cover
Copyright
Table of Contents
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
Chapter 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
Chapter 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
The Problem
Models to the Rescue
The Importance of the Bijection
Common Cases That Violate Bijection
The Effect on Language When You Build Models
Chapter 3. Anemic Models
3.0 Introduction
3.1 Converting Anemic Objects to Rich Objects
Problem
Solution
Discussion
Related Recipes
3.2 Identifying the Essence of Your Objects
Problem
Solution
Discussion
Related Recipes
3.3 Removing Setters from Objects
Problem
Solution
Discussion
Related Recipes
3.4 Removing Anemic Code Generators
Problem
Solution
Discussion
Related Recipes
3.5 Removing Automatic Properties
Problem
Solution
Discussion
Related Recipes
3.6 Removing DTOs
Problem
Solution
Discussion
Related Recipes
See Also
3.7 Completing Empty Constructors
Problem
Solution
Discussion
Related Recipes
3.8 Removing Getters
Problem
Solution
Discussion
Related Recipes
3.9 Preventing Object Orgy
Problem
Solution
Discussion
Related Recipes
3.10 Removing Dynamic Properties
Problem
Solution
Discussion
Related Recipes
Chapter 4. Primitive Obsession
4.0 Introduction
4.1 Creating Small Objects
Problem
Solution
Discussion
Related Recipes
4.2 Reifying Primitive Data
Problem
Solution
Discussion
Related Recipes
See Also
4.3 Reifying Associative Arrays
Problem
Solution
Discussion
Related Recipes
4.4 Removing String Abuses
Problem
Solution
Discussion
Related Recipes
4.5 Reifying Timestamps
Problem
Solution
Discussion
Related Recipes
4.6 Reifying Subsets as Objects
Problem
Solutions
Discussion
Related Recipes
4.7 Reifying String Validations
Problem
Solution
Discussion
Related Recipes
4.8 Removing Unnecessary Properties
Problem
Solution
Discussion
Related Recipes
4.9 Creating Date Intervals
Problem
Solution
Discussion
Related Recipes
Chapter 5. Mutability
5.0 Introduction
A Different Approach to Mutability
5.1 Changing var to const
Problem
Solution
Discussion
Related Recipes
5.2 Declaring Variables to Be Variable
Problem
Solution
Discussion
Related Recipes
5.3 Forbidding Changes in the Essence
Problem
Solution
Discussion
Related Recipes
5.4 Avoiding Mutable const Arrays
Problem
Solution
Discussion
Related Recipes
See Also
5.5 Removing Lazy Initialization
Problem
Solution
Discussion
Related Recipes
5.6 Freezing Mutable Constants
Problem
Solution
Discussion
Related Recipes
5.7 Removing Side Effects
Problem
Solution
Discussion
Related Recipes
5.8 Preventing Hoisting
Problem
Solution
Discussion
Related Recipes
See Also
Chapter 6. Declarative Code
6.0 Introduction
6.1 Narrowing Reused Variables
Problem
Solution
Discussion
Related Recipes
6.2 Removing Empty Lines
Problem
Solution
Discussion
Related Recipes
See Also
6.3 Removing Versioned Methods
Problem
Solution
Discussion
Related Recipes
6.4 Removing Double Negatives
Problem
Solution
Discussion
Related Recipes
See Also
6.5 Changing Misplaced Responsibilities
Problem
Solution
Discussion
Related Recipes
6.6 Replacing Explicit Iterations
Problem
Solution
Discussion
Related Recipes
6.7 Documenting Design Decisions
Problem
Solution
Discussion
Related Recipes
6.8 Replacing Magic Numbers with Constants
Problem
Solution
Discussion
Related Recipes
6.9 Separating “What” and “How”
Problem
Solution
Discussion
Related Recipes
6.10 Documenting Regular Expressions
Problem
Solution
Discussion
Related Recipes
6.11 Rewriting Yoda Conditions
Problem
Solution
Discussion
Related Recipes
6.12 Removing Comedian Methods
Problem
Solution
Discussion
Related Recipes
6.13 Avoiding Callback Hell
Problem
Solution
Discussion
Related Recipes
6.14 Generating Good Error Messages
Problem
Solution
Discussion
Related Recipes
6.15 Avoiding Magic Corrections
Problem
Solution
Discussion
Related Recipes
Chapter 7. Naming
7.0 Introduction
7.1 Expanding Abbreviations
Problem
Solution
Discussion
Related Recipes
7.2 Renaming and Breaking Helpers and Utils
Problem
Solution
Discussion
Related Recipes
7.3 Renaming MyObjects
Problem
Solution
Discussion
7.4 Renaming Result Variables
Problem
Solution
Discussion
Related Recipes
See Also
7.5 Renaming Variables Named After Types
Problem
Solution
Discussion
Related Recipes
7.6 Renaming Long Names
Problem
Solution
Discussion
Related Recipes
See Also
7.7 Renaming Abstract Names
Problem
Solution
Discussion
Related Recipes
7.8 Correcting Spelling Mistakes
Problem
Solution
Discussion
Related Recipes
7.9 Removing Class Names from Attributes
Problem
Solution
Discussion
Related Recipes
7.10 Removing the First Letter from Classes and Interfaces
Problem
Solution
Discussion
Related Recipes
7.11 Renaming Basic / Do Functions
Problem
Solution
Discussion
7.12 Converting Plural Classes to Singular
Problem
Solution
Discussion
7.13 Removing “Collection” from Names
Problem
Solution
Discussion
Related Recipes
7.14 Removing “Impl” Prefix/Suffix from Class Names
Problem
Solution
Discussion
Related Recipes
7.15 Renaming Arguments According to Role
Problem
Solution
Discussion
Related Recipes
7.16 Removing Redundant Parameter Names
Problem
Solution
Discussion
Related Recipes
7.17 Removing Gratuitous Context from Names
Problem
Solution
Discussion
Related Recipes
7.18 Avoiding Data Naming
Problem
Solution
Discussion
Related Recipes
Chapter 8. Comments
8.0 Introduction
8.1 Removing Commented Code
Problem
Solution
Discussion
Related Recipes
8.2 Removing Obsolete Comments
Problem
Solution
Discussion
Related Recipes
8.3 Removing Logical Comments
Problem
Solution
Discussion
Related Recipes
8.4 Removing Getter Comments
Problem
Solution
Discussion
Related Recipes
8.5 Converting Comments to Function Names
Problem
Solution
Discussion
Related Recipes
8.6 Removing Comments Inside Methods
Problem
Solution
Discussion
Related Recipes
8.7 Replacing Comments with Tests
Problem
Solution
Discussion
Related Recipes
Chapter 9. Standards
9.0 Introduction
9.1 Following Code Standards
Problem
Solution
Discussion
Related Recipes
9.2 Standardizing Indentations
Problem
Solution
Discussion
Related Recipes
9.3 Unifying Case Conventions
Problem
Solution
Discussion
Related Recipes
9.4 Writing Code in English
Problem
Solution
Discussion
9.5 Unifying Parameter Order
Problem
Solution
Discussion
Related Recipes
9.6 Fixing Broken Windows
Problem
Solution
Discussion
Related Recipes
Chapter 10. Complexity
10.0 Introduction
10.1 Removing Repeated Code
Problem
Solution
Discussion
Related Recipes
10.2 Removing Settings/Configs and Feature Toggles
Problem
Solution
Discussion
Related Recipes
10.3 Changing State as Properties
Problem
Solution
Discussion
Related Recipes
10.4 Removing Cleverness from Code
Problem
Solution
Discussion
Related Recipes
10.5 Breaking Multiple Promises
Problem
Solution
Discussion
10.6 Breaking Long Chains of Collaborations
Problem
Solution
Discussion
Related Recipes
10.7 Extracting a Method to an Object
Problem
Solution
Discussion
Related Recipes
See Also
10.8 Looking After Array Constructors
Problem
Solution
Discussion
Related Recipes
10.9 Removing Poltergeist Objects
Problem
Solution
Discussion
Related Recipes
Chapter 11. Bloaters
11.0 Introduction
11.1 Breaking Too Long Methods
Problem
Solution
Discussion
Related Recipes
See Also
11.2 Reducing Excess Arguments
Problem
Solution
Discussion
Related Recipes
11.3 Reducing Excess Variables
Problem
Solution
Discussion
Related Recipes
11.4 Removing Excessive Parentheses
Problem
Solution
Discussion
Related Recipes
11.5 Removing Excess Methods
Problem
Solution
Discussion
Related Recipes
See Also
11.6 Breaking Too Many Attributes
Problem
Solution
Discussion
Related Recipes
11.7 Reducing Import Lists
Problem
Solution
Discussion
Related Recipes
11.8 Breaking “And” Functions
Problem
Solution
Discussion
Related Recipes
11.9 Breaking Fat Interfaces
Problem
Solution
Discussion
Related Recipes
Chapter 12. YAGNI
12.0 Introduction
12.1 Removing Dead Code
Problem
Solution
Discussion
Related Recipes
12.2 Using Code Instead of Diagrams
Problem
Solution
Discussion
Related Recipes
See Also
12.3 Refactoring Classes with One Subclass
Problem
Solution
Discussion
Related Recipes
12.4 Removing One-Use Interfaces
Problem
Solution
Discussion
Related Recipes
12.5 Removing Design Pattern Abuses
Problem
Solution
Discussion
Related Recipes
12.6 Replacing Business Collections
Problem
Solution
Discussion
Related Recipes
Chapter 13. Fail Fast
13.0 Introduction
13.1 Refactoring Reassignment of Variables
Problem
Solution
Discussion
Related Recipes
13.2 Enforcing Preconditions
Problem
Solution
Discussion
Related Recipes
See Also
13.3 Using Stricter Parameters
Problem
Solution
Discussion
Related Recipes
13.4 Removing Default from Switches
Problem
Solution
Discussion
Related Recipes
13.5 Avoiding Modifying Collections While Traversing
Problem
Solution
Discussion
Related Recipes
13.6 Redefining Hash and Equality
Problem
Solution
Discussion
Related Recipes
13.7 Refactoring Without Functional Changes
Problem
Solution
Discussion
Chapter 14. Ifs
14.0 Introduction
14.1 Replacing Accidental Ifs with Polymorphism
Problem
Solution
Discussion
14.2 Renaming Flag Variables for Events
Problem
Solution
Discussion
Related Recipes
14.3 Reifying Boolean Variables
Problem
Solution
Discussion
Related Recipes
See Also
14.4 Replacing Switch/Case/Elseif Statements
Problem
Solution
Discussion
Related Recipes
14.5 Replacing Hardcoded If Conditions with Collections
Problem
Solution
Discussion
Related Recipes
14.6 Changing Boolean to Short-Circuit Conditions
Problem
Solution
Discussion
Related Recipes
14.7 Adding Implicit Else
Problem
Solution
Discussion
Related Recipes
14.8 Rewriting Conditional Arrow Code
Problem
Solution
Discussion
Related Recipes
14.9 Avoiding Short-Circuit Hacks
Problem
Solution
Discussion
Related Recipes
14.10 Rewriting Nested Arrow Code
Problem
Solution
Discussion
Related Recipes
See Also
14.11 Preventing Return Boolean Values for Condition Checks
Problem
Solution
Discussion
Related Recipes
14.12 Changing Comparison Against Booleans
Problem
Solution
Discussion
Related Recipes
14.13 Extracting from Long Ternaries
Problem
Solution
Discussion
Related Recipes
14.14 Converting Nonpolymorphic Functions to Polymorphic
Problem
Solution
Discussion
Related Recipes
14.15 Changing Equal Comparison
Problem
Solution
Discussion
Related Recipes
14.16 Reifying Hardcoded Business Conditions
Problem
Solution
Discussion
Related Recipes
14.17 Removing Gratuitous Booleans
Problem
Solution
Discussion
Related Recipes
14.18 Rewriting Nested Ternaries
Problem
Solution
Discussion
Related Recipes
Chapter 15. Null
15.0 Introduction
15.1 Creating Null Objects
Problem
Solution
Discussion
See Also
15.2 Removing Optional Chaining
Problem
Solution
Discussion
Related Recipes
See Also
15.3 Converting Optional Attributes to a Collection
Problem
Solution
Discussion
Related Recipes
15.4 Using Real Objects for Null
Problem
Solution
Discussion
Related Recipes
15.5 Representing Unknown Locations Without Using Null
Problem
Solution
Discussion
Related Recipes
See Also
Chapter 16. Premature Optimization
16.0 Introduction
16.1 Avoiding IDs on Objects
Problem
Solution
Discussion
Related Recipes
See Also
16.2 Removing Premature Optimization
Problem
Solution
Discussion
Related Recipes
See Also
16.3 Removing Bitwise Premature Optimizations
Problem
Solution
Discussion
Related Recipes
16.4 Reducing Overgeneralization
Problem
Solution
Discussion
Related Recipes
16.5 Changing Structural Optimizations
Problem
Solution
Discussion
Related Recipes
16.6 Removing Anchor Boats
Problem
Solution
Discussion
Related Recipes
16.7 Extracting Caches from Domain Objects
Problem
Solution
Discussion
Related Recipes
16.8 Removing Callback Events Based on Implementation
Problem
Solution
Discussion
Related Recipes
16.9 Removing Queries from Constructors
Problem
Solution
Discussion
Related Recipes
16.10 Removing Code from Destructors
Problem
Solution
Discussion
Related Recipes
Chapter 17. Coupling
17.0 Introduction
17.1 Making Hidden Assumptions Explicit
Problem
Solution
Discussion
Related Recipes
See Also
17.2 Replacing Singletons
Problem
Solution
Discussion
Related Recipes
17.3 Breaking God Objects
Problem
Solution
Discussion
Related Recipes
17.4 Breaking Divergent Change
Problem
Solution
Discussion
Related Recipes
See Also
17.5 Converting 9999 Special Flag Values to Normal
Problem
Solution
Discussion
Related Recipes
17.6 Removing Shotgun Surgery
Problem
Solution
Discussion
17.7 Removing Optional Arguments
Problem
Solution
Discussion
Related Recipes
17.8 Preventing Feature Envy
Problem
Solution
Discussion
Related Recipes
17.9 Removing the Middleman
Problem
Solution
Discussion
Related Recipes
See Also
17.10 Moving Default Arguments to the End
Problem
Solution
Discussion
Related Recipes
See Also
17.11 Avoiding the Ripple Effect
Problem
Solution
Discussion
Related Recipes
17.12 Removing Accidental Methods on Business Objects
Problem
Solution
Discussion
17.13 Removing Business Code from the User Interface
Problem
Solution
Discussion
Related Recipes
17.14 Changing Coupling to Classes
Problem
Solution
Discussion
Related Recipes
17.15 Refactoring Data Clumps
Problem
Solution
Discussion
Related Recipes
17.16 Breaking Inappropriate Intimacy
Problem
Solution
Discussion
Related Recipes
See Also
17.17 Converting Fungible Objects
Problem
Solution
Discussion
Related Recipes
Chapter 18. Globals
18.0 Introduction
18.1 Reifying Global Functions
Problem
Solution
Discussion
Related Recipes
18.2 Reifying Static Functions
Problem
Solution
Discussion
Related Recipes
18.3 Replacing GoTo with Structured Code
Problem
Solution
Discussion
Related Recipes
See Also
18.4 Removing Global Classes
Problem
Solutions
Discussion
Related Recipes
18.5 Changing Global Date Creation
Problem
Solution
Discussion
Related Recipes
Chapter 19. Hierarchies
19.0 Introduction
19.1 Breaking Deep Inheritance
Problem
Solution
Discussion
Related Recipes
19.2 Breaking Yo-Yo Hierarchies
Problem
Solution
Discussion
Related Recipes
See Also
19.3 Breaking Subclassification for Code Reuse
Problem
Solution
Discussion
Related Recipes
19.4 Replacing “is-a” Relationship with Behavior
Problem
Solution
Discussion
Related Recipes
See Also
19.5 Removing Nested Classes
Problem
Solution
Discussion
See Also
19.6 Renaming Isolated Classes
Problem
Solution
Discussion
Related Recipes
19.7 Making Concrete Classes Final
Problem
Solution
Discussion
Related Recipes
See Also
19.8 Defining Class Inheritance Explicitly
Problem
Solution
Discussion
Related Recipes
See Also
19.9 Migrating Empty Classes
Problem
Solution
Discussion
Related Recipes
19.10 Delaying Premature Classification
Problem
Solution
Discussion
Related Recipes
19.11 Removing Protected Attributes
Problem
Solution
Discussion
Related Recipes
19.12 Completing Empty Implementations
Problem
Solution
Discussion
Related Recipes
Chapter 20. Testing
20.0 Introduction
20.1 Testing Private Methods
Problem
Solution
Discussion
Related Recipes
See Also
20.2 Adding Descriptions to Assertions
Problem
Solution
Discussion
See Also
20.3 Migrating assertTrue to Specific Assertions
Problem
Solution
Discussion
Related Recipes
20.4 Replacing Mocks with Real Objects
Problem
Solution
Discussion
Related Recipes
20.5 Refining Generic Assertions
Problem
Solution
Discussion
Related Recipes
20.6 Removing Flaky Tests
Problem
Solution
Discussion
Related Recipes
20.7 Changing Float Number Assertions
Problem
Solution
Discussion
Related Recipes
20.8 Changing Test Data to Realistic Data
Problem
Solution
Discussion
Related Recipes
See Also
20.9 Protecting Tests Violating Encapsulation
Problem
Solution
Discussion
Related Recipes
See Also
20.10 Removing Irrelevant Test Information
Problem
Solution
Discussion
Related Recipes
20.11 Adding Coverage for Every Merge Request
Problem
Solution
Discussion
Related Recipes
20.12 Rewriting Tests Depending on Dates
Problem
Solution
Discussion
Related Recipes
20.13 Learning a New Programming Language
Problem
Solution
Discussion
See Also
Chapter 21. Technical Debt
21.0 Introduction
21.1 Removing Production-Dependent Code
Problem
Solution
Discussion
Related Recipes
21.2 Removing Defect Trackers
Problem
Solution
Discussion
Related Recipes
See Also
21.3 Removing Warning/Strict Off
Problem
Solution
Discussion
Related Recipes
See Also
21.4 Preventing and Removing ToDos and FixMes
Problem
Solution
Discussion
Related Recipes
Chapter 22. Exceptions
22.0 Introduction
22.1 Removing Empty Exception Blocks
Problem
Solution
Discussion
Related Recipes
See Also
22.2 Removing Unnecessary Exceptions
Problem
Solution
Discussion
Related Recipes
22.3 Rewriting Exceptions for Expected Cases
Problem
Solution
Discussion
Related Recipes
See Also
22.4 Rewriting Nested Try/Catches
Problem
Solution
Discussion
Related Recipes
See Also
22.5 Replacing Return Codes with Exceptions
Problem
Solution
Discussion
Related Recipes
See Also
22.6 Rewriting Exception Arrow Code
Problem
Solution
Discussion
Related Recipes
22.7 Hiding Low-Level Errors from End Users
Problem
Solution
Discussion
Related Recipes
22.8 Narrowing Exception Tries
Problem
Solution
Discussion
Related Recipes
Chapter 23. Metaprogramming
23.0 Introduction
23.1 Removing Metaprogramming Usage
Problem
Solution
Discussion
23.2 Reifying Anonymous Functions
Problem
Solution
Discussion
Related Recipes
23.3 Removing Preprocessors
Problem
Solution
Discussion
Related Recipes
See Also
23.4 Removing Dynamic Methods
Problem
Solution
Discussion
Related Recipes
Chapter 24. Types
24.0 Introduction
24.1 Removing Type Checking
Problem
Solution
Discussion
Related Recipes
24.2 Dealing with Truthy Values
Problem
Solution
Discussion
Related Recipes
24.3 Changing Float Numbers to Decimals
Problem
Solution
Discussion
Related Recipes
See Also
Chapter 25. Security
25.0 Introduction
25.1 Sanitizing Inputs
Problem
Solution
Discussion
Related Recipes
See Also
25.2 Changing Sequential IDs
Problem
Solution
Discussion
See Also
Related Recipes
25.3 Removing Package Dependencies
Problem
Solution
Discussion
Related Recipes
See Also
25.4 Replacing Evil Regular Expressions
Problem
Solution
Discussion
Related Recipes
See Also
25.5 Protecting Object Deserialization
Problem
Solution
Discussion
Related Recipes
See Also
Glossary of Terms
Index
About the Author
Colophon