Colophon
Your Rights As A Reader
Dedication
Preface
What This Book Is About
Who Should Read This Book
Before You Read This Book
How To Read This Book
Code Examples
Errata
About the Authors
About the Translators
Introduction
1. Rediscovering Simplicity
1.1. Simplifying Code
1.1.1. Incomprehensibly Concise
1.1.2. Speculatively General
1.1.3. Concretely Abstract
1.1.4. Shameless Green
1.2. Judging Code
1.2.1. Evaluating Code Based on Opinion
1.2.2. Evaluating Code Based on Facts
1.2.3. Comparing Solutions
1.3. Summary
2. Test Driving Shameless Green
2.1. Understanding Testing
2.2. Writing the First Test
2.3. Removing Duplication
2.4. Tolerating Duplication
2.5. Hewing to the Plan
2.6. Exposing Responsibilities
2.7. Choosing Names
2.8. Revealing Intentions
2.9. Writing Cost-Effective Tests
2.10. Avoiding the Echo-Chamber
2.11. Considering Options
2.12. Summary
3. Unearthing Concepts
3.1. Listening to Change
3.2. Starting With the Open/Closed Principle
3.3. Recognizing Code Smells
3.4. Identifying the Best Point of Attack
3.5. Refactoring Systematically
3.6. Following the Flocking Rules
3.7. Converging on Abstractions
3.7.1. Focusing on Difference
3.7.2. Simplifying Hard Problems
3.7.3. Naming Concepts
3.7.4. Making Methodical Transformations
3.7.5. Refactoring Gradually
3.8. Summary
4. Practicing Horizontal Refactoring
4.1. Replacing Difference With Sameness
4.2. Equivocating About Names
4.3. Deriving Names From Responsibilities
4.4. Choosing Meaningful Defaults
4.5. Seeking Stable Landing Points
4.6. Obeying the Liskov Substitution Principle
4.7. Taking Bigger Steps
4.8. Discovering Deeper Abstractions
4.9. Depending on Abstractions
4.10. Summary
5. Separating Responsibilities
5.1. Selecting the Target Code Smell
5.1.1. Identifying Patterns in Code
5.1.2. Spotting Common Qualities
5.1.3. Enumerating Flocked Method Commonalities
5.1.4. Insisting Upon Messages
5.2. Extracting Classes
5.2.1. Modeling Abstractions
5.2.2. Naming Classes
5.2.3. Extracting BottleNumber
5.2.4. Removing Arguments
5.2.5. Trusting the Process
5.3. Appreciating Immutability
5.4. Assuming Fast Enough
5.5. Creating BottleNumbers
5.6. Recognizing Liskov Violations
5.7. Summary
6. Achieving Openness
6.1. Consolidating Data Clumps
6.2. Making Sense of Conditionals
6.3. Replacing Conditionals with Polymorphism
6.3.1. Dismembering Conditionals
6.3.2. Manufacturing Objects
6.3.3. Prevailing with Polymorphism
6.4. Transitioning Between Types
6.5. Making the Easy Change
6.6. Defending the Domain
6.7. Summary
7. Manufacturing Intelligence
7.1. Contrasting the Concrete Factory with Shameless Green
7.2. Fathoming Factories
7.3. Opening the Factory
7.4. Supporting Arbitrary Class Names
7.5. Dispersing The Choosing Logic
7.6. Self-registering Candidates
7.7. Auto-registering Candidates
7.8. Summary
8. Developing a Programming Aesthetic
8.1. Appreciating the Mechanical Process
8.2. Clarifying Responsibilities with Pseudocode
8.3. Extracting the Verse
8.4. Coding by Wishful Thinking
8.5. Inverting Dependencies
8.5.1. Injecting Dependencies
8.5.2. Isolating Variants
8.5.3. Grappling with Inversion
8.6. Obeying the Law of Demeter
8.6.1. Understanding the Law
8.6.2. Curing Demeter Violations
8.7. Identifying What The Verse Method Wants
8.8. Pushing Object Creation to the Edge
8.9. Summary
9. Reaping the Benefits of Design
9.1. Choosing Which Units to Test
9.1.1. Contrasting Unit and Integration Tests
9.1.2. Foregoing Tests
9.2. Reorganizing Tests
9.2.1. Gathering BottleVerse Tests
9.2.2. Revealing Intent
9.3. Seeking Context Independence
9.3.1. Examining Bottles' Responsibilities
9.3.2. Purifying Tests With Fakes
9.3.3. Purging Redundant Tests
9.3.4. Profiting from Loose Coupling
9.4. Communicating With the Future
9.4.1. Enriching Code with Signals
9.4.2. Verifying Roles
9.4.3. Obliterating Obsolete Context
9.5. Summary
Afterword
Appendix A: Initial Exercise
Getting the exercise
Doing the exercise
Test Suite
References
Acknowledgements
This book is about writing cost-effective, maintainable, and pleasing code.Chapter 1 explores how to decide if code is "good enough." This chapter uses metrics to compare several possible solutions to the 99 Bottles problem. It introduces a type of solution known asShameless Green, and argues that although Shameless Green is neither clever nor changeable, it is the best initial solution to many problems.Chapter 2 is a primer for Test-Driven Development (TDD), which is used to find Shameless Green. This chapter is concerned with deciding what to test, and with creating tests that happily tolerate changes to the underlying code.Chapter 3 introduces a new requirement (six-pack), which leads to a discussion of how to decide where to start when changing code. This chapter examines the Open/Closed Principle, and thenexplores code smells. The chapter then defines a simple set of Flocking Rules, which guide a step-by-step refactoring of code.Chapter 4 continues the step-by-step refactoring begun in Chapter 3. It iteratively applies the Flocking Rules, eventually stumbles across the need for the Liskov Substitution Principle, and ultimately unearths a deeply hidden abstraction.Chapter 5 inventories the existing code for smells, chooses the most prominent one, and uses it to trigger the creation of a new class. Along the way, it takes a hard look at immutability, performance, and caching.Chapter 6 performs a miracle that not only removes the conditionals, but also allows you to finally implement the new six-pack requirement without altering existing code.Chapter 7 examines the tradeoffs along a continuum of six different styles of Factories. It begins by exploring a simple, hard-coded conditional, and ends with a factory whose candidate objects both self-register, and also supply the logic needed to choose them.Chapter 8 introduces another new requirement—to vary the lyrics. It uses this requirement to introduce the idea of a programming aesthetic, or set of rules to guide you in times of uncertainty. The chapter ends with a list of specific suggestions for deciding when it’s worthwhile to voluntarily improve code.Chapter 9 comes full circle and returns to testing. It takes advantage of the improved