_ (leading underscore), in function names, 386
== operator (Ruby), 255
add method (for collections), 170
Add Parameter. See Change Function Declaration
Agile software methods, 63
Algorithms, substituting, 195–196, 230, 309
Alternative classes with different interfaces, 83
Ambler, Scott, 70
Application Programming Interfaces (APIs), refactoring, 126–128
Architecture
decaying over time, 47
testability of, 99
Arrays, sorting, 173
Assertion libraries (Mocha framework), 92
Assertions
introducing, 84, 98, 129, 208, 211, 249–250, 302–304
Assignments
removing to parameters, 112
Assumptions, for values, 302
Automated refactoring tools, 131
Babel, 37
Bazuzi, Jay, 60
Beck, Kent, 10, 44, 46, 48, 65–67, 71, 77, 86–87, 107
Boundary conditions, 97
Branch by abstraction tactic, 54
Brant, John, 68
Budgeting resources, 64
Bugs
introducing into code, 4–5, 59, 129
C# language, automated refactorings in, 68
C++ language, refactorings in
for framework development, 67
safe, 60
Calculations
vs. using variables, 248
Chai assertion library, 92
Change Function Declaration, 12–13, 17, 36, 69, 72, 80, 83–84, 124–131, 141–142, 147, 175–176, 184, 214, 216, 218, 222, 245–246, 253, 286, 310, 312, 325–326, 332, 345–346, 351–352, 366, 376, 379, 403
Change Reference to Value, 76, 169, 175, 183, 185, 252–255
Change Signature. See Change Function Declaration
Change Value to Reference, 175, 256–258, 402
Chrysler Comprehensive Compensation, 65
Classes
abstract, 80
advantages of, 174
alternative, with different interfaces, 83
as data holders, 83
combining functions into, 74, 76–77, 144–148, 274, 281, 290, 293
containing their own tests, 85
context of, 198
creating, 142
extracting, 76, 78–80, 82, 182–185, 186, 199, 253, 319, 376
immutable, 330
no fields in class definitions of, 354
polymorphic, 126
redundancy in, 82
renaming, 183
vs. transform functions, 144, 149, 153
Clock wrapper, 109
Code
adding functionality to, 46, 50, 53, 56
alternative classes with different interfaces, 83
comments, 84
data class, 83
data clumps, 78
divergent change, 76
insider trading, 82
large class, 82
lazy element, 80
long parameter list, 74
loops, 79
message chains, 81
mysterious name, 72
repeated switches, 79
shotgun surgery, 76
speculative generality, 80
temporary field, 80
bad smells of:
type code, 336
communicating what it is doing, 10, 18, 51, 72–73, 107, 124–125, 137, 260, 263, 267, 302
complexity of, 260
cost of production of, 65
dead, removing, 80, 237, 249–250, 295, 320–321, 345, 347, 366, 383
dependencies in, 324–325, 327, 330
duplicated. See Duplicated code
easy to modify, 4–5, 43, 45, 47, 49
free of side effects, 75, 225, 306–309
improving, 47
observable behavior of, 45–46, 59
ownership of, 57
self-testing, 5, 59–60, 63, 85–87, 302
structure of, 23–24, 124, 154–155
adding, 272
losing over time, 47
symmetrical, 373
thought as “done”, 53
understanding, 4, 7, 24, 33, 43, 45, 47–48, 51, 54, 60, 119, 198, 207, 223, 244, 315, 327
Code analysis tools, 315
Code reviews, 54
Collecting variables, 240
Collection pipelines, 171, 231–236
Collections
empty, 96
encapsulating, 163, 169, 170–173
immutable, 171
modifier methods for, 170
Combine Functions into Class, 74, 76–77, 144–148, 153, 199, 274, 281, 290, 293
Combine Functions into Transform, 76–77, 144, 149–153, 290, 297–300
Command pattern, 338
Command-query separation principle, 225, 306, 338
Commands (command objects), 337–343
naming, 338
replaced with functions, 344–347
Comments, 84
for assumptions, 302
for dead code, 237
signaling code to extract, 73, 84, 107
turning into names, 125
Compilers
chain of phases in, 155
removing dead code in, 237
Compile-test-commit cycle, 9, 37
Compiling
after each change, 8
checks during, 108
Conditionals
consolidating, 263–265, 267, 270
replacing with:
polymorphism, 39–41, 79, 272–288, 359, 363, 366
signaling code to extract, 74
sliding statements with, 226
symmetrical, 373
Consolidate Conditional Expression, 263–265, 267, 270
Consolidate Duplicate Conditional Fragments. See Slide Statements
const keyword (JavaScript), 94, 242
Constants
creating, 242
Constructors
manipulating fields in, 331
naming, 334
pulling up body of, 355–358, 376
replacing with factory functions, 39, 334–336, 356, 363–364, 370–371, 382, 385
Continuous Delivery (CD), 60, 64
Continuous Integration (CI), 58–60, 63
Coupling
between sub- and superclasses, 400
reducing, 125
removing, 330
Data
detecting changes to, 135
duplicated, 249
mutable, 75–76, 132, 151, 162, 170, 248
Data classes, 83
accessing, 223
copying, 169
multiple copies of, 256
nested, 252
read-only proxy for, 168
when to change, 207
Data transformation functions. See Transform functions
Databases, refactoring, 61, 70
Date.now method, 109
Dead code, removing, 80, 237, 249–250, 295, 320–321, 345, 347, 366, 383
Debugging
time spent on, 85
using:
variables, 119
Decompose Conditional, 260–262, 315–318
Deep copies, 168
Delegates
hiding, 81–82, 189–191, 192, 203
replacing:
Delegation, 81
Dependencies, in code, 324–325, 327, 330
Derived variables, 75, 248–251
Design stamina hypothesis, 50
Divergent change, 76
Duplicated code, 47, 72, 82, 213, 249
for common behavior, 289
for fields, 353, 376, 378, 380
for methods, 350
for validation checks, 98
in tests, 94
replacing with function calls, 222, 310–313
searching for, 108
else statement, 267
Emacs text editor
macros in, 69
running tests in, 93
Encapsulate Collection, 163, 169, 170–173
Encapsulate Field. See Encapsulate Variable
Encapsulate Record, 83, 133, 145–146, 162–169, 210, 245
Encapsulate Variable, 75, 132–136, 137–138, 163–164, 166, 171, 175, 193–194, 249, 364
Encapsulation, 81
applicability of, 189
equals method, 254
equals method (Object), 255
Errors
explicit vs. from a default branch, 40
using assertions for, 302, 304
vs. failures, 98
Evolutionary architecture, 63
execute method, 340
Expand-contract pattern, 61
Explicit methods, replacing parameters with, 314–318
Expressions
names for, 119
Extensible Markup Language (XML), 163
Extract Class, 76, 78–80, 82, 182–185, 186, 199, 253, 319, 376
inversed. See Inline Class
Extract Function, 7, 19–20, 24, 69, 72–77, 81, 83–84, 106–114, 119, 126, 128, 130, 145–147, 150–152, 155–156, 167, 181, 214–215, 218–219, 223–224, 228–229, 261, 263–265, 273, 283–284, 290, 292, 296, 299, 302, 304, 322, 325, 328–329, 342, 344–345, 356, 370–372, 376, 388
automated, 9
inversed. See Inline Function
vs. Extract Variable, 122
Extract Method. See Extract Function
Extract Subclass. See Replace Type Code with Subclasses
Extract Superclass, 82–83, 375–379, 383, 395
Extract Variable, 119–122, 130, 322, 328–329, 345–346
inversed. See Inline Variable
vs. Extract Function, 122
Extreme Programming (XP), 60, 63, 67
replacing constructors with, 334–336, 356, 363–364, 370–371, 382, 385
returning superclass, 389
Failures
getting information about, 92
intermittent, 94
vs. errors, 98
Feathers, Michael, 70
Fields
duplicated in subclasses, 353, 376, 378, 380
moving, 77, 82, 183–184, 188, 207–212
naming, 137
persistent, 137
pulling up, 351, 353–354, 376, 378, 380
pushing down, 83, 361, 363, 380
replacing subclasses with, 369–374
self-encapsulating, 176, 193–194, 209
temporary, 80
Fields, Jay, 70
Flag arguments, removing, 74, 314–318
Foote, Brian, 80
Form Template Method, 351
Function as Object pattern, 145
Functional programming, 75
Functions
changing declaration of, 36, 124–131, 253, 310, 312, 325–326, 332, 345–346, 351, 366, 376, 403
combining into:
classes, 74, 76–77, 144–148, 153, 199, 274, 281, 290, 293
transforms, 76–77, 144, 149–153, 290, 297–300
communicating with functions from another module, 77, 198, 319
creating, 322
encapsulating, 337
explicit, replacing parameters with, 315–316
extracting, 7–11, 21, 69, 72–77, 81, 83–84, 106–114, 119, 126, 128, 130, 145–147, 150–152, 155–156, 167, 181, 214–215, 218–219, 223–224, 228–229, 261, 263–265, 273, 283–284, 290, 292, 296, 299, 302, 304, 322, 325, 328–329, 342, 344–345, 356, 370–372, 376, 388
after inlining, 115
factory, 275, 282, 334–336, 356, 363–364, 370–371, 382, 385, 389
inlining, 38, 77, 80–81, 115–118, 126, 128–130, 188, 193–194, 199, 214, 216, 218–220, 290, 294, 320–321, 328–329, 332–333, 345–347
when to avoid, 138
long, 73–74, 77, 106, 260, 338–343
matching up, 83
moving, 27, 37, 76–83, 108, 145–146, 148, 151, 167, 183–184, 187, 198–206, 323, 338–339, 370, 372, 383, 387, 391–394
naming, 7, 18, 21, 73, 106–107, 124, 130, 151, 222, 260, 284, 320
nested, 22–23, 108, 114, 145, 179, 200–204, 343
parameterizing, 51, 62, 310–313, 351
parameters of:
choosing, 125
length of lists of, 73, 74, 319, 324
removing, 126–127, 143, 324–326
referential transparency of, 327, 330
removing, 40
renaming, 21, 57, 69, 72, 80, 84, 125, 125, 127–128, 130, 147, 175–176, 184, 201, 203–204, 214, 216, 218, 221–222, 245–246, 286, 321, 352, 379
replaced with commands, 73, 337–343
replacing:
restricting visibility of, 204
returning a value, 225, 306–309
syntax errors in, 37
testing, 145
using instead of variables, 178–179
See also Methods
Gamma, Eric, 86
Generalization hierarchy, 278
Getters
returning a copy of data, 135, 171
Git version control system, 9
mutable, 75
Graphical test runners, 93
Harold, Elliotte Rusty, 70
Harvey, Shane, 70
hashcode method (Object), 255
Hashmaps, 162
Hide Delegate, 81–82, 189–191, 192
inversed. See Remove Middle Man
Hierarchy
Hypertext Markup Language (HTML), refactoring, 70
if statement, 267
Immutable fields, 83
Incremental design, 63
Indirection, needless, 115
planned in advantage, 376
inversed. See Extract Class
Inline code, replacing with function calls, 108, 222
Inline Function, 38, 77, 80–81, 115–118, 126, 128–130, 188, 193–194, 199, 214, 216, 218–220, 290, 294, 320–321, 328–329, 332–333, 345–347
inversed. See Extract Function
Inline Method. See Inline Function
Inline Temp. See Inline Variable
Inline Variable, 11, 14, 19–20, 123, 130, 147, 152–153, 181, 293, 328, 372
inversed. See Extract Variable
Input parameters, 242
Insider trading, 82
Instance variables, 82
Integrated Development Environments (IDEs)
refactoring capabilities in, 69
renaming functions automatically in, 127
running tests in, 92
Interfaces
adjusting after extracting a class, 183
marking as deprecated, 57
published, 57
Intermittent failures, 94
Introduce Assertion, 84, 98, 129, 208, 211, 249–250, 302–304
Introduce Explaining Variable. See Extract Variable
Introduce Null Object. See Introduce Special Case
Introduce Parameter Object, 73–74, 78–79, 140–143, 145, 319
Introduce Special Case, 81, 289–301
Java language
accessing collections in, 171
automated refactorings in, 68–69
constructors in, 334
equality testing in, 255
running tests in, 92
JavaScript language
accessing properties in, 389
constants in, 94
constructors in, 364
dynamic typing in, 291
error messages in, 98
exported variables in, 139
function visibility in, 204
getters and setters in, 134
nested functions in, 343
no value-based references in, 254
polymorphism in, 278
restricting visibility of variables in, 134
self-references in, 319
shallow copies in, 27
sorting arrays in, 173
subclasses in, 291
JavaScript Object Notation (JSON), 163
Jeffries, Ron, 66
JetBrains, 68
Johnson, Ralph, 67
JUnit framework, 86
Language servers, 70
Large classes, 82
Law of Demeter, the, 192
Lazy elements, 80
encapsulating data in, 133
Libraries, changing gradually, 53–54
List-and-hash data structure, 168
Lists, 163
inheritance and, 399
returning a copy of, 135
Literal objects, 295
Local variables
advantages of, 119
passed as parameters, 108, 110–111
Lodash library, 168
Long functions, 73–74, 77, 106, 260, 338–343
Long parameter lists, 73, 74, 319, 324
Loops, 79
repeating, 20
replacing with pipeline, 30, 79, 230, 231–236, 372
signaling code to extract, 74
Managers, justifying refactoring for, 54–55
Mercurial tool, 9
Message chains, 81
Methods
duplicated in subclasses, 350
explicit, replacing parameters with, 315–316
getting. See Getters
pulling up, 72, 350–352, 356, 358, 376–380
pushing down, 83, 359–360, 363, 366, 380
setting. See Setters
See also Functions
Middle man, 81
Modifiers, separating from queries, 75, 179, 264, 306–309
Modules
reducing coupling of, 125
referential transparency of, 327, 330
structuring, 82
Monetary values, storing as integers, 18
Move Field, 77, 82, 183–184, 188, 207–212
Move Function, 27, 37, 76–83, 108, 145–146, 148, 151, 167, 183, 187, 198–206, 323, 338–339, 370, 372, 383, 387, 391–394
Move Method. See Move Function
Move Statements into Function, 213–216
Move Statements to Callers, 117–118, 155, 213, 217–221, 285
encapsulating, 170
objects vs. records for, 162
Mysterious names, 72
Names
communicating what things are doing, 7, 10, 18, 51, 72–73, 107, 124–125, 137, 260, 284
deep design issues and, 72
temporary, 130
new operator, 334
NodeJS console, 91
now method (Date), 109
Null Object. See Introduce Special Case
Object-oriented languages
equality testing in, 255
inheritance mechanism in, 381
polymorphism in, 273
Objects
benefits of, 122
creating by creation script, 331
for mutable data, 162
initializing, 334
nested, 252
preserving whole, 73–74, 78, 319–323
replacing primitive types with, 79, 174–177, 363, 367
Opdyke, Bill, 67
Overloaded getter setter practice, 134
Paracelsus, 75
Parallel change pattern, 61
Parameter lists, length of, 73, 74, 319, 324
Parameter objects
introducing, 73–74, 78–79, 140–143, 145, 319
preserving whole, 73–74, 78, 319–323
Parameterize Function, 51, 62, 310–313, 351
Parameterize Method. See Parameterize Function
Parameters
adding, 62, 127, 128–129, 141–142
choosing, 125
extracting, 322
replacing with queries, 74, 324–326
unneeded, 80
Performance
accessing collections and, 171
improving, vs. cost of production, 65
large data structures and, 169
multiple copies of data and, 256
refactoring and, 14, 20, 64–67, 228
Phases, splitting, 76–77, 83, 154–159
Pipelines, replacing loops with, 30, 230, 231–236, 372
changing methods/classes with, 126
replacing conditionals with, 39–41, 79, 272–288, 363, 366
Preserve Whole Object, 73–74, 78, 319–323
Primitive types, replacing with objects, 79, 174–177, 363, 367
Productivity
and code base health, 55
and refactoring, 48–50, 56, 67
and writing tests, 100
Programming
functional, 75
object-oriented. See Object-oriented languages
Programs. See Code
protected keyword, 354
Proxies, for data structures, 168
Pull Up Constructor Body, 354, 355–358, 376
Pull Up Field, 351, 353–354, 376, 378, 380
Pull Up Method, 72, 350–352, 356, 358, 376–380
Push Down Field, 83, 361, 363, 380
Push Down Method, 83, 359–360, 363, 366, 380
Queries
replaced with parameters, 327–330
replacing:
separating from modifiers, 75, 179, 264, 306–309
Records
changing, 210
encapsulating, 83, 133, 145–146, 162–169, 210, 245
Refactoring
automated tools for, 131
comprehension, 51
embedded into code reviews, 54
exercises to practice, 70
first step in, 5
fitting into workflow, 50, 63–64
impacting software architecture, 62–63
in small steps, 8, 20–21, 44, 46, 59, 102, 245
litter-pickup, 52
long-term, 53
performance and, 14, 20, 64–67, 228
planned vs. opportunistic, 52–53
preserving observable behavior of code, 45–46, 59, 67, 98
productivity and, 48–50, 56, 67
reasons to perform, 5, 43–44, 47–50, 56–57
separating from optimization, 64–67, 228
when to avoid, 55
Refactoring Browser (Smalltalk), 68
Refactorings
definition of, 45
naming, 101
References
changing to values, 76, 169, 175, 183, 185, 252–255
changing values to, 175, 256–258, 402
Referential transparency, 327, 330
remove method (for collections), 170
Remove Assignments to Parameters. See Split Variable
Remove Dead Code, 80, 237, 249–250, 295, 320–321, 345, 347, 366, 383
Remove Flag Argument, 74, 314–318
Remove Middle Man, 81, 192–194
inversed. See Hide Delegate
Remove Parameter. See Change Function Declaration
Remove Setting Method, 75, 83, 171, 173, 253, 255, 331–333
inversed. See Replace Type Code with Subclasses
Rename Field, 72, 244–247, 354
Rename Function, Rename Method. See Change Function Declaration
Repeated switches, 79
Repetitive code. See Duplicated code
Replace Command with Function, 344–347
Replace Conditional with Polymorphism, 34, 39, 79, 272–288, 359, 363, 366
Replace Constructor with Factory Function, 39, 334–336, 356, 363–364, 370–371, 382, 385
Replace Constructor with Factory Method. See Replace Constructor with Factory Function
Replace Data Value with Object. See Replace Primitive with Object
Replace Derived Variable with Query, 75, 248–251
Replace Function with Command, 73, 337–343
Replace Inheritance with Delegation. See Replace Superclass with Delegate
Replace Inline Code with Function Call, 108, 222
Replace Loop with Pipeline, 30, 79, 230, 231–236, 372
Replace Method with Method Object. See Replace Function with Command
Replace Nested Conditional with Guard Clauses, 266–271
Replace Parameter with Explicit Methods. See Remove Flag Argument
Replace Parameter with Method. See Replace Parameter with Query
Replace Parameter with Query, 74, 324–326
Replace Primitive with Object, 79, 174–177, 363, 367
Replace Query with Parameter, 327–330
Replace Subclass with Delegate, 81–82, 84, 381–398
Replace Subclass with Fields. See Remove Subclass
Replace Superclass with Delegate, 81–82, 84, 376, 399–404
Replace Temp with Query, 11, 19, 73, 108, 114, 119, 178–181, 325
Replace Type Code with Class. See Replace Primitive with Object
Replace Type Code with State/Strategy. See Replace Type Code with Subclasses
Replace Type Code with Subclasses, 38, 79, 82, 362–368
inversed. See Remove Subclass
Repository objects, 257
Resharper plug-in, 68
Responsibility, shifting, 324, 327–328
Restructuring, 46
Ruby language
equality testing in, 255
refactoring in, 70
Rule of three, the, 50
Self Delegation tactic, 77
Self-Encapsulate Field. See Encapsulate Variable
Self-references, 319
Separate Query from Modifier, 75, 179, 264, 306–309
Setters
removing, 75, 83, 171, 173, 253, 255, 331–333
returning a copy of data, 135–136
Shallow copies, 27
Shotgun surgery, 76
Side effects, 75, 225, 306–309
Simple design, 63
Slide Statements, 18–20, 72, 75, 112, 210, 214, 217, 223–226, 229, 356–357
See also Swap Statement
Smalltalk, 67
Refactoring Browser, 68
subclass responsibility errors in, 352
using short methods in, 107
Smells. See Code, bad smells in
Software. See Code
Special cases, introducing, 81, 289–301
Speculative generality, 80
Split Loop, 18, 20, 74, 227–230
Split Phase, 24, 76–77, 83, 154–159
Split Temp. See Split Variable
Split Variable, 75, 108, 112, 114, 225, 240–243, 249–250
State design pattern, 382
Statements
moving:
to callers, 117–118, 155, 213, 217–221, 285
sliding, 72, 75, 112, 210, 214, 217, 223–226, 229, 356–357
Static typing, 127
Strategy design pattern, 77, 382
Subclass responsibility errors, 352
Subclasses
duplicated code in, 72
overriding methods in, 116, 282
pulling up:
fields, 353–354, 376, 378, 380
methods, 350–352, 358, 376–380
refusing implementations, 84
replacing:
type code with, 79, 82, 362–368
with delegates, 81–82, 84, 381–398
Substitute Algorithm, 195–196, 230, 309
Superclasses
defining constructors for, 356
extracting, 82–83, 375–379, 383, 395
pushing down:
methods, 359–360, 363, 366, 380
replacing with delegates, 81–82, 84, 376, 399–404
role of, 278
with interfaces not supported in subclasses, 84
Swap Statement, 226
See also Slide Statements
Switches
repeated, 79
signaling code to extract, 74
System clock, calls to, 109
Teardown, 95
Telephone numbers
adding logic to, 174
behavior of, separated into a class, 183–185
formatting, 125
Temporary fields, 80
Temporary variables (temps), 16
replacing with queries, 73, 108, 114, 119, 178–181, 325
Test coverage analysis, 99
Test-Driven Development, 87
adding to legacy code, 60
affecting productivity, 86, 100
choosing how many to write, 93, 98, 100
duplicated code in, 94
evolving over time, 99
failing, 21
intermittently, 94
for boundary conditions, 97
for setters, 95
importance of, 5
in IDE, 92
running:
after each change, 8
self-checking, 5, 59–60, 63, 85–87, 302
teardown between, 95
this keyword (JavaScript), 319
Thomas, Dave, 85
Transform functions, 76–77, 149–153
Trunk-Based Development, 58
Type code
passing as a literal string, 336
replacing with:
Type-instance homonym, 400
undefined property (JavaScript), 389
Underscore (_), in function names, 386
Understanding code, 4, 7, 24, 33, 43, 45, 47–48, 51, 54, 119, 223
and flag arguments, 315
importance of data structures for, 207, 244
in legacy systems, 60
removing dead code for, 237
Uniform Access Principle (UAP), 147
Validation checks, 98
Value objects, 141, 185, 252–255
Values
changing references to, 76, 169, 175, 183, 185, 252–255
changing to references, 175, 256–258, 402
encapsulating, 135
free of side effects, 225, 306–309
immutable, 162
self-references to, 319
Variables, 240
bundling in a class, 82
declared as input parameters, 242
declaring/initializing, 21, 223, 241
encapsulating, 75, 132–136, 137–138, 163–164, 166, 171, 175, 249
extracting, 119–122, 130, 322, 328–329, 345–346
global, 133
highlighting in text editors, 241
inlining, 11, 14, 19, 21, 123, 130, 147, 152–153, 181, 293, 328, 372
instance, 82
out-of-scope, 108
renaming, 9–10, 16, 22, 51, 69, 72, 134, 137–139, 241
replacing with:
restricting visibility of, 134
splitting, 75, 108, 114, 225, 240–243, 249–250
temporary, 16
useful for debugging, 119
Version control systems
committing:
after each refactoring, 9
separately for refactorings and feature additions, 53
retrieving deleted code in, 237
Visitor design pattern, 77
Visual Studio, refactoring in, 68
Wake, Bill, 70
XML (Extensible Markup Language), 163