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