Refactoring catalog - gregswindle/eslint-plugin-crc GitHub Wiki
- 📖 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/
- Add Parameter
- Change Bidirectional Association to Unidirectional
- Change Reference to Value
- Change Unidirectional Association to Bidirectional
- Change Value to Reference
- Collapse Hierarchy
- Consolidate Conditional Expression
- Consolidate Duplicate Conditional Fragments
- Decompose Conditional
- Duplicate Observed Data
- Dynamic Method Definition
- Eagerly Initialized Attribute
- Encapsulate Collection
- Encapsulate Downcast
- Encapsulate Field
- Extract Class
- Extract Interface
- Extract Method
- Extract Module
- Extract Subclass
- Extract Superclass
- Extract Surrounding Method
- Extract Variable
- Form Template Method
- Hide Delegate
- Hide Method
- Inline Class
- Inline Method
- Inline Module
- Inline Temp
- Introduce Assertion
- Introduce Class Annotation
- Introduce Expression Builder
- Introduce Foreign Method
- Introduce Gateway
- Introduce Local Extension
- Introduce Named Parameter
- Introduce Null Object
- Introduce Parameter Object
- Isolate Dynamic Receptor
- Lazily Initialized Attribute
- Move Eval from Runtime to Parse Time
- Move Field
- Move Method
- Parameterize Method
- Preserve Whole Object
- Pull Up Constructor Body
- Pull Up Field
- Pull Up Method
- Push Down Field
- Push Down Method
- Recompose Conditional
- Remove Assignments to Parameters
- Remove Control Flag
- Remove Middle Man
- Remove Named Parameter
- Remove Parameter
- Remove Setting Method
- Remove Unused Default Parameter
- Rename Method
- Replace Abstract Superclass with Module
- Replace Array with Object
- Replace Conditional with Polymorphism
- Replace Constructor with Factory Method
- Replace Data Value with Object
- Replace Delegation With Hierarchy
- Replace Delegation with Inheritance
- Replace Dynamic Receptor with Dynamic Method Definition
- Replace Error Code with Exception
- Replace Exception with Test
- Replace Hash with Object
- Replace Inheritance with Delegation
- Replace Loop with Collection Closure Method
- Replace Magic Number with Symbolic Constant
- Replace Method with Method Object
- Replace Nested Conditional with Guard Clauses
- Replace Parameter with Explicit Methods
- Replace Parameter with Method
- Replace Record with Data Class
- Replace Subclass with Fields
- Replace Temp with Chain
- Replace Temp with Query
- Replace Type Code with Class
- Replace Type Code with Module Extension
- Replace Type Code With Polymorphism
- Replace Type Code with State/Strategy
- Replace Type Code with Subclasses
- Self Encapsulate Field
- Separate Query from Modifier
- Split Temporary Variable
- Substitute Algorithm
Categories:
A method needs more information from its caller.
Add a parameter for an object that can pass on this information.
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:
A superclass and subclass are not very different.
Merge them together.
Categories:
You have a sequence of conditional tests with the same result.
Combine them into a single conditional expression and extract it.
Categories:
The same fragment of code is in all branches of a conditional expression.
Move it outside of the expression.
Categories:
You have a complicated conditional (if-then-else) statement.
Extract methods from the condition, then part, and else parts.
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 methods that can be defined more concisely if defined dynamically.
Define the methods dynamically.
Categories:
Lazily initialization is causing more confusion than benefit
Initialize the attribute when you instantiate the object
Categories:
A method returns a collection.
Make it return a read-only view and provide add/remove methods.
Categories:
A method returns an object that needs to be downcasted by its callers.
Move the downcast to within the method.
Categories:
There is a public field.
Make it private and provide accessors.
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 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 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 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:
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 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:
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:
A class isn't doing very much.
Move all its features into another class and delete it.
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:
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:
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:
A section of code assumes something about the state of the program.
Make the assumption explicit with an assertion.
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:
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:
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:
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
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:
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:
You have repeated checks for a null value.
Replace the null value with a null object.
Categories:
You have a group of parameters that naturally go together.
Replace them with an object.
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:
An attribute takes time to initialize but is only accessed rarely
Initialize when it's first used
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:
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:
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 are getting several values from an object and passing these values as parameters in a method call.
Send the whole object instead.
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 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:
The code assigns to a parameter.
Use a temporary variable instead.
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:
A class is doing too much simple delegation.
Get the client to call the delegate directly.
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:
A field should be set at creation time and never altered.
Remove any setting method for that field.
Categories:
A parameter has a default value, but the method is never called without the parameter.
Remove the default value
Categories:
The name of a method does not reveal its purpose.
Change the name of the method.
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 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 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:
You want to do more than simple construction when you create an object.
Replace the constructor with a factory method.
Categories:
You have a data item that needs additional data or behavior.
Turn the data item into an object.
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:
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 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 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:
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:
You are processing the elements of a collection in a loop.
Replace the loop with a collection closure method.
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:
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:
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 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 need to interface with a record structure in a traditional programming environment.
Make a dumb data object for the record.
Categories:
You have subclasses that vary only in methods that return constant data.
Change the methods to superclass fields and eliminate the subclasses.
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:
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 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 an immutable type code that affects the behavior of a class.
Replace the type code with subclasses.
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:
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:
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:
You want to replace an algorithm with one that is clearer.
Replace the body of the method with the new algorithm.