Tags
Fowler, M. (2013, December 10). Catalog of Refactorings. Retrieved November 18, 2017, from https://refactoring.com/catalog/
Refactorings by tag
- GOF Patterns
- associations
- Change Bidirectional Association to Unidirectional
- Change Reference to Value
- Change Unidirectional Association to Bidirectional
- Change Value to Reference
- Duplicate Observed Data
- Extract Class
- Inline Class
- Replace Delegation With Hierarchy
- Replace Delegation with Inheritance
- Replace Inheritance with Delegation
- Replace Method with Method Object
- class extraction
- composing methods
- conditionals
- defining methods
- encapsulation
- errors
- generic types
- inheritance
- interfaces
- local variables
- method calls
- moving features
- organizing data
- type codes
- vendor libraries
GOF Patterns
Form Template Method
Categories:
Problem
You have two methods in subclasses that perform similar steps in the same order, yet the steps are different.
Solution
Get the steps into methods with the same signature, so that the original methods become the same. Then you can pull them up.
Replace Type Code with State/Strategy
Categories:
Problem
You have a type code that affects the behavior of a class, but you cannot use subclassing.
Solution
Replace the type code with a state object.
:arrow_up_small: Table of contents
associations
Change Bidirectional Association to Unidirectional
Categories:
Problem
You have a two-way association but one class no longer needs features from the other.
Solution
Drop the unneeded end of the association.
Change Reference to Value
Categories:
Problem
You have a reference object that is small, immutable, and awkward to manage.
Solution
Turn it into a value object.
Change Unidirectional Association to Bidirectional
Categories:
Problem
You have two classes that need to use each other's features, but there is only a one-way link.
Solution
Add back pointers, and change modifiers to update both sets.
Change Value to Reference
Categories:
Problem
You have a class with many equal instances that you want to replace with a single object.
Solution
Turn the object into a reference object.
Duplicate Observed Data
Categories:
Problem
You have domain data available only in a GUI control, and domain methods need access.
Solution
Copy the data to a domain object. Set up an observer to synchronize the two pieces of data.
Extract Class
Categories:
Problem
You have one class doing work that should be done by two.
Solution
Create a new class and move the relevant fields and methods from the old class into the new class.
Inline Class
Categories:
Problem
A class isn't doing very much.
Solution
Move all its features into another class and delete it.
Replace Delegation With Hierarchy
Categories:
Problem
You’re using delegation and are often writing many simple delegations for the entire interface
Solution
Make the delegate a module and include it into the delegating class.
Replace Delegation with Inheritance
Categories:
Problem
You're using delegation and are often writing many simple delegations for the entire interface.
Solution
Make the delegating class a subclass of the delegate.
Replace Inheritance with Delegation
Categories:
Problem
A subclass uses only part of a superclasses interface or does not want to inherit data.
Solution
Create a field for the superclass, adjust methods to delegate to the superclass, and remove the subclassing.
Replace Method with Method Object
Categories:
associations local variables composing methods defining methods
Problem
You have a long method that uses local variables in such a way that you cannot apply
Solution
Turn the method into its own object so that all the local variables become fields on that object. You can then decompose the method into other methods on the same object.
:arrow_up_small: Table of contents
class extraction
Extract Class
Categories:
Problem
You have one class doing work that should be done by two.
Solution
Create a new class and move the relevant fields and methods from the old class into the new class.
Extract Interface
Categories:
Problem
Several clients use the same subset of a class's interface, or two classes have part of their interfaces in common.
Solution
Extract the subset into an interface.
Extract Module
Categories:
Problem
You have duplicated behavior in two or more classes.
Solution
You have duplicated behavior in two or more classes.
Extract Subclass
Categories:
Problem
A class has features that are used only in some instances.
Solution
Create a subclass for that subset of features.
Extract Superclass
Categories:
Problem
You have two classes with similar features.
Solution
Create a superclass and move the common features to the superclass.
Introduce Parameter Object
Categories:
Problem
You have a group of parameters that naturally go together.
Solution
Replace them with an object.
:arrow_up_small: Table of contents
composing methods
Extract Method
Categories:
Problem
You have a code fragment that can be grouped together.
Solution
Turn the fragment into a method whose name explains the purpose of the method.
Extract Surrounding Method
Categories:
Problem
You have two methods that contain nearly identical code. The variance is in the middle of the method.
Solution
Extract the duplication into a method that accepts a block and yields back to the caller to execute the unique code.
Inline Method
Categories:
Problem
A method's body is just as clear as its name.
Solution
Put the method's body into the body of its callers and remove the method.
Move Eval from Runtime to Parse Time
Categories:
Problem
You need to use eval but want to limit the number of times eval is necessary.
Solution
Move the use of eval from within the method definition to defining the method itself.
Replace Loop with Collection Closure Method
Categories:
Problem
You are processing the elements of a collection in a loop.
Solution
Replace the loop with a collection closure method.
Substitute Algorithm
Categories:
Problem
You want to replace an algorithm with one that is clearer.
Solution
Replace the body of the method with the new algorithm.
:arrow_up_small: Table of contents
conditionals
Consolidate Conditional Expression
Categories:
Problem
You have a sequence of conditional tests with the same result.
Solution
Combine them into a single conditional expression and extract it.
Decompose Conditional
Categories:
Problem
You have a complicated conditional (if-then-else) statement.
Solution
Extract methods from the condition, then part, and else parts.
Consolidate Duplicate Conditional Fragments
Categories:
Problem
The same fragment of code is in all branches of a conditional expression.
Solution
Move it outside of the expression.
Introduce Assertion
Categories:
Problem
A section of code assumes something about the state of the program.
Solution
Make the assumption explicit with an assertion.
Recompose Conditional
Categories:
Problem
You have conditional code that is unnecessarily verbose and does not use the most readable Ruby construct.
Solution
Replace the conditional code with the more idiomatic Ruby construct.
Replace Nested Conditional with Guard Clauses
Categories:
Problem
A method has conditional behavior that does not make clear what the normal path of execution is
Solution
Use Guard Clauses for all the special cases
:arrow_up_small: Table of contents
defining methods
Dynamic Method Definition
Categories:
Problem
You have methods that can be defined more concisely if defined dynamically.
Solution
Define the methods dynamically.
Introduce Class Annotation
Categories:
Problem
You have a method whose implementation steps are so common that they can safely be hidden away.
Solution
Declare the behavior by calling a class method from the class definition.
Isolate Dynamic Receptor
Categories:
Problem
A class utilizing method_missing has become painful to alter.
Solution
Introduce a new class and move the method_missing logic to that class.
Remove Unused Default Parameter
Categories:
Problem
A parameter has a default value, but the method is never called without the parameter.
Solution
Remove the default value
Replace Dynamic Receptor with Dynamic Method Definition
Categories:
Problem
You have methods you want to handle dynamically without the pain of debug- gingmethod_missing.
Solution
Use dynamic method definition to define the necessary methods.
:arrow_up_small: Table of contents
encapsulation
Encapsulate Collection
Categories:
Problem
A method returns a collection.
Solution
Make it return a read-only view and provide add/remove methods.
Encapsulate Field
Categories:
Problem
There is a public field.
Solution
Make it private and provide accessors.
Self Encapsulate Field
Categories:
Problem
You are accessing a field directly, but the coupling to the field is becoming awkward.
Solution
Create getting and setting methods for the field and use only those to access the field.
Encapsulate Downcast
Categories:
Problem
A method returns an object that needs to be downcasted by its callers.
Solution
Move the downcast to within the method.
Hide Delegate
Categories:
Problem
A client is calling a delegate class of an object.
Solution
Create methods on the server to hide the delegate.
Hide Method
Categories:
Problem
A method is not used by any other class.
Solution
Make the method private.
Preserve Whole Object
Categories:
Problem
You are getting several values from an object and passing these values as parameters in a method call.
Solution
Send the whole object instead.
Remove Setting Method
Categories:
Problem
A field should be set at creation time and never altered.
Solution
Remove any setting method for that field.
:arrow_up_small: Table of contents
errors
Replace Error Code with Exception
Categories:
Problem
A method returns a special code to indicate an error.
Solution
Throw an exception instead.
Replace Exception with Test
Categories:
Problem
You are throwing an exception on a condition the caller could have checked first.
Solution
Change the caller to make the test first.
:arrow_up_small: Table of contents
generic types
Replace Array with Object
Categories:
Problem
You have an array in which certain elements mean different things.
Solution
Replace the array with an object that has a field for each element.
Replace Data Value with Object
Categories:
Problem
You have a data item that needs additional data or behavior.
Solution
Turn the data item into an object.
Replace Hash with Object
Categories:
Problem
You have a hash that stores several different types of objects, and is passed around and used for more than one purpose.
Solution
Replace the hash with an object that has a field for each key
Replace Magic Number with Symbolic Constant
Categories:
Problem
You have a literal number with a particular meaning.
Solution
Create a constant, name it after the meaning, and replace the number with it.
Replace Record with Data Class
Categories:
Problem
You need to interface with a record structure in a traditional programming environment.
Solution
Make a dumb data object for the record.
:arrow_up_small: Table of contents
inheritance
Collapse Hierarchy
Categories:
Problem
A superclass and subclass are not very different.
Solution
Merge them together.
Pull Up Constructor Body
Categories:
Problem
You have constructors on subclasses with mostly identical bodies.
Solution
Create a superclass constructor; call this from the subclass methods.
Pull Up Field
Categories:
Problem
Two subclasses have the same field.
Solution
Move the field to the superclass.
Pull Up Method
Categories:
Problem
You have methods with identical results on subclasses.
Solution
Move them to the superclass.
Push Down Field
Categories:
Problem
A field is used only by some subclasses.
Solution
Move the field to those subclasses.
Push Down Method
Categories:
Problem
Behavior on a superclass is relevant only for some of its subclasses.
Solution
Move it to those subclasses.
Replace Abstract Superclass with Module
Categories:
Problem
You have an inheritance hierarchy, but never intend to explicitly instantiate an instance of the superclass.
Solution
Replace the superclass with a module to better communicate your intention.
Introduce Null Object
Categories:
Problem
You have repeated checks for a null value.
Solution
Replace the null value with a null object.
Replace Conditional with Polymorphism
Categories:
Problem
You have a conditional that chooses different behavior depending on the type of an object.
Solution
Move each leg of the conditional to an overriding method in a subclass. Make the original method abstract.
:arrow_up_small: Table of contents
interfaces
Extract Interface
Categories:
Problem
Several clients use the same subset of a class's interface, or two classes have part of their interfaces in common.
Solution
Extract the subset into an interface.
Replace Constructor with Factory Method
Categories:
Problem
You want to do more than simple construction when you create an object.
Solution
Replace the constructor with a factory method.
:arrow_up_small: Table of contents
local variables
Extract Variable
Categories:
Problem
You have a complicated expression.
Solution
Put the result of the expression, or parts of the expression, in a temporary variable with a name that explains the purpose.
Inline Temp
Categories:
Problem
You have a temp that is assigned to once with a simple expression, and the temp is getting in the way of other refactorings.
Solution
Replace all references to that temp with the expression.
Remove Assignments to Parameters
Categories:
Problem
The code assigns to a parameter.
Solution
Use a temporary variable instead.
Replace Method with Method Object
Categories:
associations local variables composing methods defining methods
Problem
You have a long method that uses local variables in such a way that you cannot apply
Solution
Turn the method into its own object so that all the local variables become fields on that object. You can then decompose the method into other methods on the same object.
Replace Temp with Chain
Categories:
Problem
You are using a temporary variable to hold the result of an expression
Solution
Change the methods to support chaining, thus removing the need for a temp.
Replace Temp with Query
Categories:
Problem
You are using a temporary variable to hold the result of an expression.
Solution
Extract the expression into a method. Replace all references to the temp with the expression. The new method can then be used in other methods.
Split Temporary Variable
Categories:
Problem
You have a temporary variable assigned to more than once, but is not a loop variable nor a collecting temporary variable.
Solution
Make a separate temporary variable for each assignment.
:arrow_up_small: Table of contents
method calls
Add Parameter
Categories:
Problem
A method needs more information from its caller.
Solution
Add a parameter for an object that can pass on this information.
Introduce Expression Builder
Categories:
Problem
You want to interact with a public interface in a more fluent manner and not muddy the interface of an existing object.
Solution
Introduce an Expression Builder and create an interface specific to your application.
Introduce Named Parameter
Categories:
Problem
The parameters in a method call cannot easily be deduced from the name of the method you are calling.
Solution
Convert the parameter list into a Hash, and use the keys of the Hash as names for the parameters.
Parameterize Method
Categories:
Problem
Several methods do similar things but with different values contained in the method body.
Solution
Create one method that uses a parameter for the different values.
Remove Control Flag
Categories:
Problem
You have a variable that is acting as a control flag for a series of boolean expressions.
Solution
Use a break or return instead.
Remove Named Parameter
Categories:
Problem
The fluency that the named parameter brings is no longer worth the complexity on the receiver.
Solution
Convert the named parameter Hash to a standard parameter list.
Remove Parameter
Categories:
Problem
A parameter is no longer used by the method body.
Solution
Remove it.
Rename Method
Categories:
Problem
The name of a method does not reveal its purpose.
Solution
Change the name of the method.
Replace Parameter with Explicit Methods
Categories:
Problem
You have a method that runs different code depending on the values of an enumerated parameter.
Solution
Create a separate method for each value of the parameter.
Replace Parameter with Method
Categories:
Problem
An object invokes a method, then passes the result as a parameter for a method. The receiver can also invoke this method.
Solution
Remove the parameter and let the receiver invoke the method.
Separate Query from Modifier
Categories:
Problem
You have a method that returns a value but also changes the state of an object.
Solution
Create two methods, one for the query and one for the modification.
:arrow_up_small: Table of contents
moving features
Inline Module
Categories:
Problem
The resultant indirection of the included module is no longer worth the duplica- tion it is preventing.
Solution
Merge the module into the including class.
Move Field
Categories:
Problem
A field is, or will be, used by another class more than the class on which it is defined.
Solution
Create a new field in the target class, and change all its users.
Move Method
Categories:
Problem
A method is, or will be, using or used by more features of another class than the class on which it is defined.
Solution
Create a new method with a similar body in the class it uses most. Either turn the old method into a simple delegation, or remove it altogether.
Remove Middle Man
Categories:
Problem
A class is doing too much simple delegation.
Solution
Get the client to call the delegate directly.
:arrow_up_small: Table of contents
organizing data
Eagerly Initialized Attribute
Categories:
Problem
Lazily initialization is causing more confusion than benefit
Solution
Initialize the attribute when you instantiate the object
Lazily Initialized Attribute
Categories:
Problem
An attribute takes time to initialize but is only accessed rarely
Solution
Initialize when it's first used
Replace Subclass with Fields
Categories:
Problem
You have subclasses that vary only in methods that return constant data.
Solution
Change the methods to superclass fields and eliminate the subclasses.
:arrow_up_small: Table of contents
type codes
Replace Type Code with Class
Categories:
Problem
A class has a numeric type code that does not affect its behavior.
Solution
Replace the number with a new class.
Replace Type Code with Module Extension
Categories:
Problem
You have a type code that affects the behavior of a class.
Solution
Replace the type code with dynamic module extension.
Replace Type Code With Polymorphism
Categories:
Problem
You have a type code that affects the behavior of a class.
Solution
Replace the type code with classes: one for each type code variant.
Replace Type Code with Subclasses
Categories:
Problem
You have an immutable type code that affects the behavior of a class.
Solution
Replace the type code with subclasses.
:arrow_up_small: Table of contents
vendor libraries
Introduce Foreign Method
Categories:
Problem
A server class you are using needs an additional method, but you can't modify the class.
Solution
Create a method in the client class with an instance of the server class as its first argument.
Introduce Local Extension
Categories:
Problem
A server class you are using needs several additional methods, but you can't modify the class.
Solution
Create a new class that contains these extra methods. Make this extension class a subclass or a wrapper of the original.
Introduce Gateway
Categories:
Problem
You want to interact with a complex API of an external system or resource in a simplified way
Solution
Introduce a Gateway that encapsulates access to an external system or resource
:arrow_up_small: Table of contents