Contents
Foreword
Preface
Introduction
PART I: The Mechanics of Change
Chapter 1: Changing Software
Four Reasons to Change Software
Risky Change
Chapter 2: Working with Feedback
What Is Unit Testing?
Higher-Level Testing
Test Coverings
The Legacy Code Change Algorithm
Chapter 3: Sensing and Separation
Faking Collaborators
Chapter 4: The Seam Model
A Huge Sheet of Text
Seams
Seam Types
Chapter 5: Tools
Automated Refactoring Tools
Mock Objects
Unit-Testing Harnesses
General Test Harnesses
PART II: Changing Software
Chapter 6: I Don’t Have Much Time and I Have to Change It
Sprout Method
Sprout Class
Wrap Method
Wrap Class
Summary
Chapter 7: It Takes Forever to Make a Change
Understanding
Lag Time
Breaking Dependencies
Summary
Chapter 8: How Do I Add a Feature?
Test-Driven Development (TDD)
Programming by Difference
Summary
Chapter 9: I Can’t Get This Class into a Test Harness
The Case of the Irritating Parameter
The Case of the Hidden Dependency
The Case of the Construction Blob
The Case of the Irritating Global Dependency
The Case of the Horrible Include Dependencies
The Case of the Onion Parameter
The Case of the Aliased Parameter
Chapter 10: I Can’t Run This Method in a Test Harness
The Case of the Hidden Method
The Case of the “Helpful” Language Feature
The Case of the Undetectable Side Effect
Chapter 11: I Need to Make a Change. What Methods Should I Test?
Reasoning About Effects
Reasoning Forward
Effect Propagation
Tools for Effect Reasoning
Learning from Effect Analysis
Simplifying Effect Sketches
Chapter 12: I Need to Make Many Changes in One Area
Interception Points
Judging Design with Pinch Points
Pinch Point Traps
Chapter 13: I Need to Make a Change, but I Don’t Know What Tests to Write
Characterization Tests
Characterizing Classes
Targeted Testing
A Heuristic for Writing Characterization Tests
Chapter 14: Dependencies on Libraries Are Killing Me
Chapter 15: My Application Is All API Calls
Chapter 16: I Don’t Understand the Code Well Enough to Change It
Notes/Sketching
Listing Markup
Scratch Refactoring
Delete Unused Code
Chapter 17: My Application Has No Structure
Telling the Story of the System
Naked CRC
Conversation Scrutiny
Chapter 18: My Test Code Is in the Way
Class Naming Conventions
Test Location
Chapter 19: My Project Is Not Object Oriented How Do I Make Safe Changes?
An Easy Case
A Hard Case
Adding New Behavior
Taking Advantage of Object Orientation
It’s All Object Oriented
Chapter 20: This Class Is Too Big and I Don’t Want It to Get Any Bigger
Seeing Responsibilities
Other Techniques
Moving Forward
After Extract Class
Chapter 21: I’m Changing the Same Code All Over the Place
First Steps
Chapter 22: I Need to Change a Monster Method and I Can’t Write Tests for It
Varieties of Monsters
Tackling Monsters with Automated Refactoring Support
The Manual Refactoring Challenge
Strategy
Chapter 23: How Do I Know That I’m Not Breaking Anything?
Hyperaware Editing
Single-Goal Editing
Preserve Signatures
Lean on the Compiler
Chapter 24: We Feel Overwhelmed. It Isn’t Going to Get Any Better
PART III: Dependency-Breaking Techniques
Chapter 25: Dependency-Breaking Techniques
Adapt Parameter
Break Out Method Object
Definition Completion
Encapsulate Global References
Expose Static Method
Extract and Override Call
Extract and Override Factory Method
Extract and Override Getter
Extract Implementer
Extract Interface
Introduce Instance Delegator
Introduce Static Setter
Link Substitution
Parameterize Constructor
Parameterize Method
Primitivize Parameter
Pull Up Feature
Push Down Dependency
Replace Function with Function Pointer
Replace Global Reference with Getter
Subclass and Override Method
Supersede Instance Variable
Template Redefinition
Text Redefinition
Appendix: Refactoring
Extract Method
Glossary
Index
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
R
S
T
U
V
W
X