Skip to content

Refactorings by category

Greg Swindle edited this page Jan 21, 2018 · 13 revisions

Refactoring defined

📖 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/

Table of contents

GOF Patterns

  1. Form Template Method
  2. Replace Type Code with State/Strategy

Associations

  1. Change Bidirectional Association to Unidirectional
  2. Change Reference to Value
  3. Change Unidirectional Association to Bidirectional
  4. Change Value to Reference
  5. Duplicate Observed Data
  6. Extract Class
  7. Inline Class
  8. Replace Delegation With Hierarchy
  9. Replace Delegation with Inheritance
  10. Replace Inheritance with Delegation
  11. Replace Method with Method Object

Class extraction

  1. Extract Class
  2. Extract Interface
  3. Extract Module
  4. Extract Subclass
  5. Extract Superclass
  6. Introduce Parameter Object

Composing methods

  1. Extract Method
  2. Extract Surrounding Method
  3. Inline Method
  4. Move Eval from Runtime to Parse Time
  5. Replace Loop with Collection Closure Method
  6. Substitute Algorithm

Conditionals

  1. Consolidate Conditional Expression
  2. Decompose Conditional
  3. Consolidate Duplicate Conditional Fragments
  4. Introduce Assertion
  5. Recompose Conditional
  6. Replace Nested Conditional with Guard Clauses

Defining methods

  1. Dynamic Method Definition
  2. Introduce Class Annotation
  3. Isolate Dynamic Receptor
  4. Remove Unused Default Parameter
  5. Replace Dynamic Receptor with Dynamic Method Definition

Encapsulation

  1. Encapsulate Collection
  2. Encapsulate Field
  3. Self Encapsulate Field
  4. Encapsulate Downcast
  5. Hide Delegate
  6. Hide Method
  7. Preserve Whole Object
  8. Remove Setting Method

Errors

  1. Replace Error Code with Exception
  2. Replace Exception with Test

Generic types

  1. Replace Array with Object
  2. Replace Data Value with Object
  3. Replace Hash with Object
  4. Replace Magic Number with Symbolic Constant
  5. Replace Record with Data Class

Inheritance

  1. Collapse Hierarchy
  2. Pull Up Constructor Body
  3. Pull Up Field
  4. Pull Up Method
  5. Push Down Field
  6. Push Down Method
  7. Replace Abstract Superclass with Module
  8. Introduce Null Object
  9. Replace Conditional with Polymorphism

Interfaces

  1. Extract Interface
  2. Replace Constructor with Factory Method

Local variables

  1. Extract Variable
  2. Inline Temp
  3. Remove Assignments to Parameters
  4. Replace Method with Method Object
  5. Replace Temp with Chain
  6. Replace Temp with Query
  7. Split Temporary Variable

Method calls

  1. Add Parameter
  2. Introduce Expression Builder
  3. Introduce Named Parameter
  4. Parameterize Method
  5. Remove Control Flag
  6. Remove Named Parameter
  7. Remove Parameter
  8. Rename Method
  9. Replace Parameter with Explicit Methods
  10. Replace Parameter with Method
  11. Separate Query from Modifier

Moving features

  1. Inline Module
  2. Move Field
  3. Move Method
  4. Remove Middle Man

Organizing data

  1. Eagerly Initialized Attribute
  2. Lazily Initialized Attribute
  3. Replace Subclass with Fields

Type codes

  1. Replace Type Code with Class
  2. Replace Type Code with Module Extension
  3. Replace Type Code With Polymorphism
  4. Replace Type Code with Subclasses

Vendor libraries

  1. Introduce Foreign Method
  2. Introduce Local Extension
  3. Introduce Gateway

GOF Patterns

Form Template Method

Categories:

GOF Patterns   inheritance   composing methods  

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.

Learn more...


Replace Type Code with State/Strategy

Categories:

GOF Patterns   type codes   organizing data  

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.

Learn more...


🔼 Table of contents


Associations

Change Bidirectional Association to Unidirectional

Categories:

associations   organizing data  

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.

Learn more...


Change Reference to Value

Categories:

associations   organizing data  

Problem

You have a reference object that is small, immutable, and awkward to manage.

Solution

Turn it into a value object.

Learn more...


Change Unidirectional Association to Bidirectional

Categories:

associations   organizing data  

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.

Learn more...


Change Value to Reference

Categories:

associations   organizing data  

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.

Learn more...


Duplicate Observed Data

Categories:

associations   organizing data  

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.

Learn more...


Extract Class

Categories:

associations   class extraction   moving features  

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.

Learn more...


Inline Class

Categories:

associations   moving features  

Problem

A class isn't doing very much.

Solution

Move all its features into another class and delete it.

Learn more...


Replace Delegation With Hierarchy

Categories:

associations   inheritance  

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.

Learn more...


Replace Delegation with Inheritance

Categories:

associations   inheritance  

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.

Learn more...


Replace Inheritance with Delegation

Categories:

associations   inheritance  

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.

Learn more...


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.

Learn more...


🔼 Table of contents


Class extraction

Extract Class

Categories:

associations   class extraction   moving features  

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.

Learn more...


Extract Interface

Categories:

interfaces   class extraction   inheritance  

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.

Learn more...


Extract Module

Categories:

class extraction   inheritance   moving features  

Problem

You have duplicated behavior in two or more classes.

Solution

You have duplicated behavior in two or more classes.

Learn more...


Extract Subclass

Categories:

class extraction   inheritance  

Problem

A class has features that are used only in some instances.

Solution

Create a subclass for that subset of features.

Learn more...


Extract Superclass

Categories:

class extraction   inheritance  

Problem

You have two classes with similar features.

Solution

Create a superclass and move the common features to the superclass.

Learn more...


Introduce Parameter Object

Categories:

class extraction   method calls  

Problem

You have a group of parameters that naturally go together.

Solution

Replace them with an object.

Learn more...


🔼 Table of contents


Composing methods

Extract Method

Categories:

composing methods  

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.

Learn more...


Extract Surrounding Method

Categories:

composing methods  

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.

Learn more...


Inline Method

Categories:

composing methods  

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.

Learn more...


Move Eval from Runtime to Parse Time

Categories:

composing methods  

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.

Learn more...


Replace Loop with Collection Closure Method

Categories:

composing methods  

Problem

You are processing the elements of a collection in a loop.

Solution

Replace the loop with a collection closure method.

Learn more...


Substitute Algorithm

Categories:

composing methods  

Problem

You want to replace an algorithm with one that is clearer.

Solution

Replace the body of the method with the new algorithm.

Learn more...


🔼 Table of contents


Conditionals

Consolidate Conditional Expression

Categories:

conditionals   composing methods  

Problem

You have a sequence of conditional tests with the same result.

Solution

Combine them into a single conditional expression and extract it.

Learn more...


Decompose Conditional

Categories:

conditionals   composing methods  

Problem

You have a complicated conditional (if-then-else) statement.

Solution

Extract methods from the condition, then part, and else parts.

Learn more...


Consolidate Duplicate Conditional Fragments

Categories:

conditionals  

Problem

The same fragment of code is in all branches of a conditional expression.

Solution

Move it outside of the expression.

Learn more...


Introduce Assertion

Categories:

conditionals  

Problem

A section of code assumes something about the state of the program.

Solution

Make the assumption explicit with an assertion.

Learn more...


Recompose Conditional

Categories:

conditionals  

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.

Learn more...


Replace Nested Conditional with Guard Clauses

Categories:

conditionals  

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

Learn more...


🔼 Table of contents


Defining methods

Dynamic Method Definition

Categories:

defining methods  

Problem

You have methods that can be defined more concisely if defined dynamically.

Solution

Define the methods dynamically.

Learn more...


Introduce Class Annotation

Categories:

defining methods  

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.

Learn more...


Isolate Dynamic Receptor

Categories:

defining methods  

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.

Learn more...


Remove Unused Default Parameter

Categories:

defining methods  

Problem

A parameter has a default value, but the method is never called without the parameter.

Solution

Remove the default value

Learn more...


Replace Dynamic Receptor with Dynamic Method Definition

Categories:

defining methods  

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.

Learn more...


🔼 Table of contents


Encapsulation

Encapsulate Collection

Categories:

encapsulation   organizing data  

Problem

A method returns a collection.

Solution

Make it return a read-only view and provide add/remove methods.

Learn more...


Encapsulate Field

Categories:

encapsulation   organizing data  

Problem

There is a public field.

Solution

Make it private and provide accessors.

Learn more...


Self Encapsulate Field

Categories:

encapsulation   organizing data  

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.

Learn more...


Encapsulate Downcast

Categories:

encapsulation   method calls   inheritance  

Problem

A method returns an object that needs to be downcasted by its callers.

Solution

Move the downcast to within the method.

Learn more...


Hide Delegate

Categories:

encapsulation   moving features  

Problem

A client is calling a delegate class of an object.

Solution

Create methods on the server to hide the delegate.

Learn more...


Hide Method

Categories:

encapsulation   method calls  

Problem

A method is not used by any other class.

Solution

Make the method private.

Learn more...


Preserve Whole Object

Categories:

encapsulation   method calls  

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.

Learn more...


Remove Setting Method

Categories:

encapsulation   method calls  

Problem

A field should be set at creation time and never altered.

Solution

Remove any setting method for that field.

Learn more...


🔼 Table of contents


Errors

Replace Error Code with Exception

Categories:

errors   method calls  

Problem

A method returns a special code to indicate an error.

Solution

Throw an exception instead.

Learn more...


Replace Exception with Test

Categories:

errors   method calls   conditionals  

Problem

You are throwing an exception on a condition the caller could have checked first.

Solution

Change the caller to make the test first.

Learn more...


🔼 Table of contents


Generic types

Replace Array with Object

Categories:

generic types   organizing data  

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.

Learn more...


Replace Data Value with Object

Categories:

generic types   organizing data  

Problem

You have a data item that needs additional data or behavior.

Solution

Turn the data item into an object.

Learn more...


Replace Hash with Object

Categories:

generic types  

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

Learn more...


Replace Magic Number with Symbolic Constant

Categories:

generic types   organizing data  

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.

Learn more...


Replace Record with Data Class

Categories:

generic types   organizing data  

Problem

You need to interface with a record structure in a traditional programming environment.

Solution

Make a dumb data object for the record.

Learn more...


🔼 Table of contents


Inheritance

Collapse Hierarchy

Categories:

inheritance  

Problem

A superclass and subclass are not very different.

Solution

Merge them together.

Learn more...


Pull Up Constructor Body

Categories:

inheritance  

Problem

You have constructors on subclasses with mostly identical bodies.

Solution

Create a superclass constructor; call this from the subclass methods.

Learn more...


Pull Up Field

Categories:

inheritance  

Problem

Two subclasses have the same field.

Solution

Move the field to the superclass.

Learn more...


Pull Up Method

Categories:

inheritance  

Problem

You have methods with identical results on subclasses.

Solution

Move them to the superclass.

Learn more...


Push Down Field

Categories:

inheritance  

Problem

A field is used only by some subclasses.

Solution

Move the field to those subclasses.

Learn more...


Push Down Method

Categories:

inheritance  

Problem

Behavior on a superclass is relevant only for some of its subclasses.

Solution

Move it to those subclasses.

Learn more...


Replace Abstract Superclass with Module

Categories:

inheritance  

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.

Learn more...


Introduce Null Object

Categories:

inheritance   conditionals  

Problem

You have repeated checks for a null value.

Solution

Replace the null value with a null object.

Learn more...


Replace Conditional with Polymorphism

Categories:

inheritance   conditionals  

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.

Learn more...


🔼 Table of contents


Interfaces

Extract Interface

Categories:

interfaces   class extraction   inheritance  

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.

Learn more...


Replace Constructor with Factory Method

Categories:

interfaces   method calls  

Problem

You want to do more than simple construction when you create an object.

Solution

Replace the constructor with a factory method.

Learn more...


🔼 Table of contents


Local variables

Extract Variable

Categories:

local variables   composing methods  

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.

Learn more...


Inline Temp

Categories:

local variables   composing methods  

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.

Learn more...


Remove Assignments to Parameters

Categories:

local variables   composing methods  

Problem

The code assigns to a parameter.

Solution

Use a temporary variable instead.

Learn more...


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.

Learn more...


Replace Temp with Chain

Categories:

local variables  

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.

Learn more...


Replace Temp with Query

Categories:

local variables   composing methods  

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.

Learn more...


Split Temporary Variable

Categories:

local variables   composing methods  

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.

Learn more...


🔼 Table of contents


Method calls

Add Parameter

Categories:

method calls  

Problem

A method needs more information from its caller.

Solution

Add a parameter for an object that can pass on this information.

Learn more...


Introduce Expression Builder

Categories:

method calls  

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.

Learn more...


Introduce Named Parameter

Categories:

method calls  

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.

Learn more...


Parameterize Method

Categories:

method calls  

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.

Learn more...


Remove Control Flag

Categories:

method calls   conditionals  

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.

Learn more...


Remove Named Parameter

Categories:

method calls  

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.

Learn more...


Remove Parameter

Categories:

method calls  

Problem

A parameter is no longer used by the method body.

Solution

Remove it.

Learn more...


Rename Method

Categories:

method calls  

Problem

The name of a method does not reveal its purpose.

Solution

Change the name of the method.

Learn more...


Replace Parameter with Explicit Methods

Categories:

method calls  

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.

Learn more...


Replace Parameter with Method

Categories:

method calls  

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.

Learn more...


Separate Query from Modifier

Categories:

method calls  

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.

Learn more...


🔼 Table of contents


Moving features

Inline Module

Categories:

moving features  

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.

Learn more...


Move Field

Categories:

moving features  

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.

Learn more...


Move Method

Categories:

moving features  

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.

Learn more...


Remove Middle Man

Categories:

moving features  

Problem

A class is doing too much simple delegation.

Solution

Get the client to call the delegate directly.

Learn more...


🔼 Table of contents


Organizing data

Eagerly Initialized Attribute

Categories:

organizing data  

Problem

Lazily initialization is causing more confusion than benefit

Solution

Initialize the attribute when you instantiate the object

Learn more...


Lazily Initialized Attribute

Categories:

organizing data  

Problem

An attribute takes time to initialize but is only accessed rarely

Solution

Initialize when it's first used

Learn more...


Replace Subclass with Fields

Categories:

organizing data   inheritance  

Problem

You have subclasses that vary only in methods that return constant data.

Solution

Change the methods to superclass fields and eliminate the subclasses.

Learn more...


🔼 Table of contents


Type codes

Replace Type Code with Class

Categories:

type codes   organizing data  

Problem

A class has a numeric type code that does not affect its behavior.

Solution

Replace the number with a new class.

Learn more...


Replace Type Code with Module Extension

Categories:

type codes  

Problem

You have a type code that affects the behavior of a class.

Solution

Replace the type code with dynamic module extension.

Learn more...


Replace Type Code With Polymorphism

Categories:

type codes  

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.

Learn more...


Replace Type Code with Subclasses

Categories:

type codes   organizing data   inheritance  

Problem

You have an immutable type code that affects the behavior of a class.

Solution

Replace the type code with subclasses.

Learn more...


🔼 Table of contents


Vendor libraries

Introduce Foreign Method

Categories:

vendor libraries   moving features  

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.

Learn more...


Introduce Local Extension

Categories:

vendor libraries   moving features  

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.

Learn more...


Introduce Gateway

Categories:

vendor libraries   method calls  

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

Learn more...


🔼 Table of contents


Clone this wiki locally