Refactoring Recipes

This is a list of general ideas to consider while refactoring. Below You will find recipes with examples.

Before refactoring make sure You have a way to test if code still works as intented. In professional environment You will have full coverage of all code branches (It does not mean full code coverage).

Important!

Code Formatting

How many lines of code should be in the module (file)? 50-100 lines each.
How long should the line be? The best is 30-40 characters long. 80-120 is the maximum.

For code formatting, You can use tools like black (for Python).

Naming

Names should reveal your intent. A name that requires a comment does not reveal its intent. The name of the variable should tell the significance of what that variable contains.

The variable name should be proportional to the size of the scope that contains it. So:

  • Variable in one line of code can be one letter variable
  • Conventional variables like i, x, y, or r can be one letter even in a slightly bigger scope but consider longer names (like radius) in a bigger scope
  • Variable in if, for or tiny function should be short (up to one word)
  • Arguments of static function should be about words long
  • Arguments of instance function should be two words long because they have a bigger scope
  • Global variables should be very long (a couple of words)

Function and class name should be inversely proportional to the size of the scope that contains it. The bigger the scope the more abstract it is. The smaller the scope the more precise it is and requires more words to describe it.

  • Global classes and functions should have one-word names
  • Instance functions of a class and derivative classes should have about two-word names
  • Private functions called public functions and inner classes should have longer names (three to four words)
  • Private functions called private functions and even inner classes should have even longer names (few words)

Names should be readable and distinguishable from each other. Consider using Comic Code or Comic Mono for your IDE and terminal. For IDE I strongly recommend JetBrains Tools.

Avoid:

  • using symbols that lookalike
  • prefixes and convenient misspellings
  • number series
  • noise words (data, info, product)

Do:

  • Distinguish names meaningfully
  • Make sure names are pronounceable

Comments

Comments explain code if it can’t explain itself. Nothing can as helpful as a good comment and nothing can be so obscure as a bad comment. Comments are not pure good. They are an unfortunate necessity.

Proper use of comments is to compensate for our failure to express ourselves in code. So every use of comment represents a failure. Don’t comment first. Try everything else, and then use the comment as the last resort.

Comments lie not intentionally, they silently rot and migrate.

Tips about comments:

  • Make comments in Your IDE RED!
  • Don’t comment on bad code – clean it.
  • Don’t commit #TODO comments.
  • Extract variables to explain things instead of writing comments
  • Write comments explaining Why something is written, not What is written

Acceptable comments:

  • Copyrights
  • Explain design pattern usage
  • Explain regular expression
  • Informative
  • Explanation of intent
  • Clarification
  • Warning of consequences
  • Docs if code is for external use

Bad comments:

  • Mumbling
  • Redundant
  • Mandated
  • Journal
  • Noise (obvious)
  • Positional markers, headers, etc.
  • Closing braces
  • Attribution and bylines
  • Commented-out code
  • HTML in comment
  • Non-local information (Comment about other code)
  • Too much information

Elegant function

The elegant function is small, as small as possible. It is small enough when You can’t extract any meaningful function out of it. Having a lot of small functions instead of fewer big ones means that each function will have a name, class, package, etc. That way there won’t be any comments and everything will have its place. The elegant function has at most three arguments and very rarely any of them is boolean. If a function has a try-block there is no more other code than it. Also, switch statements and going to like mechanics are evil. Functions should be query or command. Open-close pairs of functions should be written so that it is impossible to forget to close them (with statements in Python, lambdas). Exceptions should be subclasses of classes that throw them.

Refactoring Recipes

Composing Methods

Description

Extracting complex fragments of code or its parts to variable named after its purpose. Can be the first step to Extracting Method.

Recipe

  1. Create a new variable in a new line before the given expression
  2. Assign complex expression or its part to this variable
  3. Replace expression or its part with the new variable
  4. If necessary repeat this process for more parts of given expression
  5. Make sure code still works by running tests

Description

Replacing temporary variable with its content makes code more straightforward. This refactoring is the inverse of Extract Variable.

Recipe

  1. Replace the variable with the expression that had been assigned to it
  2. Delete the variable
  3. Make sure code still works by running tests

Description

Grouping fragments of code together and extracting it to method named after its purpose.

Recipe

Try to use IDE to help You:
  1. Create new method and name it after its purpose
  2. Move code to new method
  3. Add method call where code came from
  4. Move variables that are used only in the new method to it
  5. Use other variables as parameters of the function or Replace Temp with Query
  6. In case the method had an early return statement consider using a special variable and checking it after the method call or raising and catching some exception.
  7. Make sure code still works by running tests

Description

Replacing calls to simple methods with its body makes code more straightforward. This refactoring is the inverse of Extracting Method.

Recipe

  1. Make sure that the method is not redefined in subclasses or used widely. In that case, abandon this refactorization
  2. Replac all calls to the method with its content
  3. Remove the method
  4. Make sure code still works by running tests

Description

Removing parameters modification, to avoid confusion and unexpected behavior.

Recipe

  1. Create a local variable and assign the first value change of a parameter
  2. Replace all parameter uses with new local variable
  3. Make sure code still works by running tests

Description

Isolating a long method in its own class. It lets split this method later within a class.

Recipe

  1. Create a new class and name it after its purpose
  2. Add private fields for each local variable of the method and if some data is required from the original class add a field for its reference
  3. Add a constructor that initializes private fields with values of local variables of the method
  4. Declare a new method in a class and copy the code of the original method to it. Replace local variables with private fields
  5. Replace the body of the original method by creating a method object and calling its new method
  6. Make sure code still works by running tests

Description

Splitting temporary variable that has more than one assignment in order to make code more readable and avoid unwanted behavior.

Recipe

  1. Rename first occurrence of variable to represents its purpose
  2. Use new name where its appropriate
  3. Repeat this steps for every new assignment of this variable
  4. Make sure code still works by running tests

Description

Extracting methods from common, cheap, and small expressions in order to make code more readable and usable.

Recipe

  1. Make sure that the variable has its value assigned only once within the method. If not, use Split Temporary Variable
  2. Extract Method from given expression. Make sure that this method doesn’t change the state of the object. If it does use Separate Query from Modifier
  3. Replace the variable with a call to your new method
  4. Make sure code still works by running tests

Description

Replacing old algorithm with new implementation. Maybe the new algorithm is faster or cleaner.

Recipe

  1. Move all necessary parts with the Extracting Method to leave only the part You want to replace
  2. Create a new algorithm in a new method and replace the old call with a new one
  3. Make sure code still works by running tests
  4. If it does remove the old algorithm and run tests once again

Moving Features between Objects

Description

Moving fields to the places where are used.

Recipe

  1. For public fields use Encapsulate Field first
  2. Create a new field with access methods in the recipient class like in the original class
  3. Replace all references to the original field with calls to fields/methods in the recipient class
  4. Delete the field in the original class
  5. Make sure code still works by running tests

Description

Moving a method to a class that contains most of the data used by the method to reduce dependency between classes.

Recipe

  1. Consider moving other related parts of code together
  2. Create a new method in the recipient class
  3. Replace all references to the original method with calls to methods in the recipient class
  4. Delete the old method
  5. Make sure code still works by running tests

Description

Extracting redundant responsibilities to dedicated classes to make code cleaner and less prone to errors. This refactoring is the inverse of Inline Class.

Recipe

  1. Create a new class for chosen functionality
  2. Create reference to new class in old class
  3. Move Fields and Methods from old to new class
  4. Consider changing name of an old class
  5. Make sure code still works by running tests

Description

Moving all fields and methods from the small class to the other, where they belong. This refactoring is the inverse of Extract Class.

Recipe

  1. Create in the recipient class all public fields and methods that are in the small class
  2. Use Move Field and Move Method to transfer all functionality from small class
  3. Replace all references of a small class with new methods and fields of recipient class
  4. Delete the original class
  5. Make sure code still works by running tests

Description

Hiding the complexity of the system from clients to ease changes.

Recipe

  1. Create methods in the server class that delegates the call to the delegate class
  2. Change all calls to use server class methods
  3. Make sure code still works by running tests

Description

Add the utility method not in the best place to avoid duplication.

Recipe

  1. Create a new method in the client class
  2. Add parameter to which the object of the utility class will be passed
  3. Move code fragments to this method and replace them with method calls
  4. Make sure code still works by running tests
  5. Consider adding comment or moving this method to dedicated utility place

Description

Adding new functionality to library class.

Recipe

  1. Create child class from library class
  2. Add a constructor with parameters of the constructor of the utility class
  3. Create a second constructor that takes only the original class parameters
  4. Add new functionality to extension class
  5. Replace the use of the library class with the new extension class where it is needed
  6. Make sure code still works by running tests

Description

Removing class that only passing calls.

Recipe

  1. Create a getter for accessing the delegate class object from the server class object
  2. Replace calls to delegating methods in the server class with calls for methods in the delegate class
  3. Make sure code still works by running tests

Organizing Data

Description

Removing associations to simplify code and make it more maintainable. This refactoring is the inverse of Change Unidirectional Association to Bidirectional.

Recipe

  1. Make sure that there is no association or You can easily get required data in a different way (passing argument)
  2. Field that contains an association should be replaced by appropriate parameter or method call
  3. Delete assignment code
  4. Delete field
  5. Make sure code still works by running tests

Description

Adding associations to speed up code in case of costly calculations. This refactoring is the inverse of Change Bidirectional Association to Unidirectional.

Recipe

  1. Add a field for reverse association
  2. Create a utility method for establishing the association in the “non-dominant” class
  3. Complement “dominant” class methods with calls to utility methods from the associated object
  4. Create corresponding methods in the “dominant” class that was in the “non-dominant” class, call them, and delegate execution to them
  5. Make sure code still works by running tests

Description

Making object's states unchangable and easier to maintain for objects that don't change value during their lifetime. This refactoring is the inverse of Change Value to Reference.

Recipe

  1. Remove all methods that can change objects state (Remove Setting Method)
  2. Add a comparison method
  3. Add setting object value to constructor method if it is not already there and make it public if possible
  4. Make sure code still works by running tests

Description

Making object's states changable to save memory for repeating values or let the objects change their state during their lifetimes. This refactoring is the inverse of Change Reference to Value.

Recipe

  1. Replace Constructor with Factory Method in referencing class
  2. Change the factory method so that it returns a reference
  3. Implement a way of storing objects and time of creation (when needed or in advance)
  4. Make sure code still works by running tests

Description

Making data managed only by its owner object to make code easier to maintain.

Recipe

  1. Create a getter and setter for the field
  2. Replace previous usages of the field with the getter and setter accordingly
  3. Make field private
  4. Make sure code still works by running tests

Description

Adding getter and setter to a private fileld to add more functionality and control over it.

Recipe

  1. Create public getter (and setter if necessary) for the field
  2. Replace previous usages of the field with the getter and setter accordingly
  3. Make sure code still works by running tests

Description

Splitting responsibility between business logic and presentation classes.

Recipe

  1. Hide direct access to data in the UI class (Self Encapsulate Field)
  2. Add setters in handlers for UI events
  3. Create a domain class with necessary fields from the UI class
  4. Add getters and setters for these fields
  5. Create an Observer pattern for these two classes
  6. Make sure code still works by running tests

Description

Making implementetion of collection abstract for more flexibility and usage in different Use Cases.

Recipe

  1. Create methods for adding and deleting collection elements with collection elements as parameters
  2. Set its initial value to empty collection
  3. Change the collection field setter so that it uses operations for adding and deleting elements
  4. Change name of setters to something like "replace"
  5. Change the code so that it uses your new methods for adding and deleting elements from the collection
  6. Change the getter so that it returns a read-only representation of the collection
  7. Make sure code still works by running tests
  8. Consider moving parts of code from client to collection class

Description

Replacing small, known array with object for clarity of code.

Recipe

  1. Create the new class that will contain the data from the array and place the array in the class as a public field
  2. Add a field for storing new class in the original class
  3. Add field initialization code
  4. Create access methods one by one for each of the array elements in the new class
  5. Replace usages of the array in the main code with the corresponding access method
  6. Make the array private
  7. Create a private field in a new class for each array element and change the access methods so that they use this field
  8. Delete the array
  9. Make sure code still works by running tests

Description

Moving relevant field to separate class to make code cleaner.

Recipe

  1. Create a new class and copy your field and its getter to it
  2. Create a constructor that accepts the simple value of the field
  3. Change the field type to the new class in the original class
  4. Invoke the getter of the associated object in the getter of the original class
  5. Add creation of new value object to the setter and constructor
  6. Make sure code still works by running tests

Description

Replacing minimalistic subclasses with fields to simplify system architecture

Recipe

  1. Replace Constructor with Factory Method of the subclasses
  2. Replace subclass constructor calls with superclass factory method calls
  3. Add fields to the superclass for storing the values of each of the subclass methods that return constant values
  4. Add superclass constructor for initializing the new fields
  5. Make existing subclass constructors call the new constructor of the parent class and pass the relevant values to it
  6. Implement each constant method in the parent class so that it returns the value of the corresponding field
  7. Remove relevant methods from the subclass
  8. Inline constructor Method of subclass to superclass factory method
  9. Delete the subclass
  10. Make sure code still works by running tests

Description

Replacing non-descriptive numbers with descriptive constants to make code easier to understand and maintain.

Recipe

  1. Declare a constant and assign the value of the magic number to it
  2. Replace all uses of the magic number with constant if constant matches its purpose
  3. Make sure code still works by running tests

Description

Organizing type codes into type class to make code more readable.

Recipe

  1. Create a new type class
  2. Copy the field containing type code to the type class and make it private
  3. Create a getter for the field
  4. Add static constructors in type class for each value of the coded type
  5. In the original class replace the type of the coded field with type class and create a new object of this type in the constructor as well as in the field setter
  6. Change the field getter so that it calls the type class getter
  7. Replace coded type values with calls to the type class static methods
  8. Remove the coded type constants
  9. Make sure code still works by running tests

Description

Organizing type codes into subclasses to make code more readable.

Recipe

  1. Self Encapsulate Field to create a getter for type code field
  2. Make the superclass constructor private
  3. Create a static factory method with the same parameters as the superclass constructor
  4. Create a unique subclass for each value of the coded type and redefine the getter of the coded type so that it returns the corresponding value of the coded type
  5. Delete the field with type code from the superclass and make its getter abstract
  6. Move the fields and methods from the superclass to corresponding subclasses (Push Down Field, Push Down Method)
  7. Replace Conditional with Polymorphism in order to get rid of conditions that use the type code
  8. Make sure code still works by running tests

Description

Organizing type codes by using State/Strategy pattern to make code more readable.

Recipe

  1. Self Encapsulate Field to create a getter for type code field
  2. Create a new type class with an abstract field-getter
  3. Create subclasses of the state class for each value of the coded type and redefine the getter of the field so that it returns the corresponding value of the type
  4. In the abstract class, create a static factory method that accepts the value of the type as a parameter and creates corresponding states/strategies
  5. In the original class change the type of field to state/strategy class
  6. Adjust the field setter to make it call the factory state method
  7. Move the fields and methods from the superclass to corresponding subclasses (Push Down Field, Push Down Method)
  8. Replace Conditional with Polymorphism in order to get rid of conditions that use the type code
  9. Make sure code still works by running tests

Simplifying Conditional Expressions

Description

The name of the condition and each case's methods tells what is happening and why without reading their implementations.

Recipe

Use Extract Method to decompose conditional. Condition statement shouldn't modify anything and cases won't depend on each other making easy extraction:
  1. Extract the condition into the separate well-named method
  2. Extract all cases into their well-named methods
  3. Make sure code still works by running tests

Description

Extracting method from conditional for greater clarity.

Recipe

  1. Combine conditionals into a single expression by using "and" and "or". Nested conditionals join with "and". Consecutive conditionals join with "or"
  2. Extract Method from expression and give the method a name that reflects its purpose
  3. Make sure code still works by running tests

Description

Getting rid of duplicated code for better maintainability.

Recipe

  1. Extract Method from duplicated if the code is longer than a line or unclear
  2. Move duplicated code to the end of the beginning of the conditional branches
  3. Move duplicated code before the conditional, if it is at the beginning of the conditional branches
  4. Move duplicated code after the conditional, if it is at the end of the conditional branches
  5. Make sure code still works by running tests

Description

Replacing control flag with "break", "continue" or "return" for lighter code.

Recipe

  1. Replace value assignment to the control flag that causes the exit from the loop with "break", "continue" or "return"
  2. Remove the remaining code and checks associated with the control flag
  3. Make sure code still works by running tests

Description

Replacing assumptions with assertion code for lower risk of errors and clarity.

Recipe

  1. Add an assertion for assumed condition
  2. Write additional test for failing assertion
  3. Make sure code still works by running tests

Description

Getting rid of null checks in conditionals by using a null object to make them clearer.

Recipe

  1. Create a subclass from a given class that will represent a null object
  2. Add isNull()/isNone() method to both classes that will return an appropriate boolean
  3. Change the code so that it returns a null object when it would return null
  4. Adjust other methods of both classes with appropriate behavior from conditionals
  5. Remove conditionals branches that null object tool care of
  6. Make sure code still works by running tests

Description

Simplifying conditionals by extracting guard clauses.

Recipe

  1. Clean code from side effects with Separate Query from Modifier
  2. Move conditions, that lead to calling an exception or immediate return, to the beginning of the method
  3. Try using Consolidate Conditional Expression
  4. Make sure code still works by running tests

Description

Getting rid of duplication in conditionals by using polymorphism.

Recipe

  1. Create subclass hierarchy for each behaviour using Replace Type Code with Subclasses or Replace Type Code with State/Strategy
  2. Extract Method if the conditional is in a method that does more than just condition
  3. For all branches of conditional and corresponding subclasses, redefine the method that contains the conditional and copy the code for the corresponding conditional branch
  4. Delete the conditional and declare the main class method "abstract"
  5. Make sure code still works by running tests

Simplifying Method Calls

Description

Adding more parameters to the method, because it needs more data. Often a part of other refactorings.

Recipe

  1. Add new parameter to method
  2. Make sure it is passed everywhere the method is used or set the default for new parameter
  3. Make sure code still works by running tests

Description

Removing unnecessary parameters from the method for more clarity and simplicity.

Recipe

  1. Modify method so it does not need parameter
  2. Remove parameter
  3. Make sure it is not passed everywhere the method is used
  4. Make sure code still works by running tests

Description

Giving the method a name that reflects what it does.

Recipe

Try to use IDE to help You:
  1. Rename method name
  2. Rename all uses of method in code
  3. Make sure code still works by running tests

Description



Recipe

    Try to use static code analysis to find methods used only in the class:
  1. Set methods to private
  2. Make sure code still works by running tests

Description

Splitting method into a few methods, each with a different value of the parameter. It makes the method's name clearer and easier to understand.

Recipe

  1. Decide which parameter You will spit the method on and remove the parameter from the method
  2. Duplicate method as many times as your code needs different values of parameter
  3. For each method add a variable with the corresponding value of the removed parameter
  4. Make sure methods name are descriptive and used in the right places
  5. Make sure code still works by running tests

Description

Combining similar methos into one by introducing a parameter. It minimizes duplication.

Recipe

  1. Create a method with a parameter and move it to the code that’s the same for all classes using Extract Method
  2. In the method, replace the differing value with a parameter
  3. Replace calls to old methods with calls to the new method that with a parameter
  4. Delete the old methods
  5. Make sure code still works by running tests

Description

Removing the setting method to prevent any changes to the value of a field.

Recipe

  1. Make sure the constructor sets the value of a given parameter
  2. Remove all setter calls moving them to the constructor if applicable
  3. Replace setter calls in the class with direct access to the field
  4. Delete the setter
  5. Make sure code still works by running tests

Description

Adding Parameter Object with a comprehensible name for more readable code.

Recipe

  1. Create a immutable class (check attrs) that will represent your group of parameters
  2. Add Parameter in method You want to refactor and pass an object of created class
  3. Replace other parameters with access to fields of parameter object
  4. Make sure code still works by running tests
  5. Consider Move Method or Extract Method into new class

Description

Passing whole parameter object into methods instead of its fields for clearer code.

Recipe

  1. Add a parameter in the method for the parameter object
  2. Replace other parameters with access to fields of parameter object
  3. Delete the getter code from the parameter object if its not used anymore
  4. Make sure code still works by running tests

Description

Replacing constructor with Factory Method for better flexibility and control.

Recipe

  1. Create a Factory Method and place a call to the current constructor in it
  2. Replace constructor calls with calls to the factory method
  3. Set constructor as private
  4. Make sure code still works by running tests
  5. Consider moving code from constructor to Factory Method

Description

Removing the need for checking error codes in many places. It simplifies error handling and the rest of the code.

Recipe

  1. Wrap all method calls that return error codes in try/catch blocks
  2. Inside the method, replace returning an error code with throwing an exception
  3. Change the method name/signature so that it tells that exception can be thrown
  4. Make sure code still works by running tests

Description

Replacing exception with simple conditional check if it's done in one or two places.

Recipe

  1. Add a conditional for an edge case before the try/catch block
  2. Move code from the catch section inside the conditional
  3. Remove try/catch block
  4. Make sure code still works by running tests

Description

Getting rid of unneeded parameters and simplifying method calls.

Recipe

  1. Extract Method to isolate this code in a new method and make the call simple
  2. Replace all references to the parameter with calls to the method that gets the value
  3. Remove Parameter to eliminate the now-unused parameter
  4. Make sure code still works by running tests

Description

Splitting method into query and modifier methods for code simplification and better maintainability.

Recipe

  1. Create a query method to return what the original method did
  2. Remove value-returning code in the original method – now it's modifier method
  3. Replace all calls to the original method with a call to the query method
  4. Add modifier method line before query methods where applicable
  5. Make sure code still works by running tests

Dealing with Generalization

Description

Creating subclass to support special cases and avoid complex conditionals.

Recipe

  1. Create a new subclass from a given class
  2. Add proper constructor to new class
  3. Modify code so that it uses a new subclass and its constructor when necessary
  4. Push Down Field and Push Down Method to move responsibilities to subclass
  5. Delete unnecessary fields, now supported by subclass (polymorphism) and replace all the operators in which the fields had been used
  6. Make sure code still works by running tests

Description

Creating superclass for common functionality of similar classes, to remove duplication.

Recipe

  1. Create an abstract superclass
  2. Use Pull Up Field, Pull Up Method, and Pull Up Constructor Body to move the common functionality to a superclass
  3. Use Pull Up Field, Pull Up Method and Pull Up Constructor Body to move the common functionality to a superclass
  4. Replace subclass with superclass where it's appropriate
  5. Make sure code still works by running tests

Description

Extracting interface to add layer of abstraction. It can be useful when You have a client that can use different implementations of given functionality depending on the setup.

Recipe

  1. Create an empty interface
  2. Add common operations to the interface
  3. Create the necessary classes implementing the interface
  4. Change type declarations to use the new interface where applicable
  5. Make sure code still works by running tests

Description

Combining similar methods to Template Method to reduce duplication on a higher level.

Recipe

  1. Split algorithms from subclasses into separate steps – methods. Extract Method can be useful
  2. Pull Up Methods that are identical for all subclasses to a superclass
  3. Rename Methods that are different so that naming is consistent and
  4. Move the signatures of different methods to a superclass as abstract ones (Pull Up Method)
  5. Pull Up the main method of the algorithm to the superclass so it works with method steps
  6. Make sure code still works by running tests

Description

Pulling field up the hierarchy to get rid of duplication in subclasses.

Recipe

  1. Make sure the field is named and used the same on all subclasses
  2. Add this field in the superclass
  3. Remove the fields from the subclasses
  4. Make sure code still works by running tests

Description

Pulling method up the hierarchy to get rid of duplication in subclasses.

Recipe

  1. Make sure the methods are named, used, and has the same parameters on all subclasses
  2. Copy method to super class
  3. Pull Up Field or Self-Encapsulate Field if necessary
  4. Also Pull Up Methods that are associated with this one
  5. Remove the methods from the subclasses
  6. Replace use of a subclass with the superclass where possible
  7. Make sure code still works by running tests

Description

Pulling constructor up the hierarchy to get rid of duplication in subclasses.

Recipe

  1. Create a constructor in a superclass
  2. Extract the common code the constructor of each subclass to the superclass constructor
  3. Add the call for the superclass constructor in the subclass constructors
  4. Make sure code still works by running tests

Description

Pushing field down the hierarchy to improve class coherence.

Recipe

  1. Add a field in all the necessary subclasses
  2. Remove the field from the superclass
  3. Make sure code still works by running tests

Description

Pushing method down the hierarchy to improve class coherence.

Recipe

  1. Add the method in a subclass and fill it with code from the superclass
  2. Remove the method from the superclass
  3. Use calls to subclass method where necessary
  4. Make sure code still works by running tests

Description

Removing delegation classes to reduce code length.

Recipe

  1. Turn the given class into a subclass of the delegate class
  2. Put the given object into a field with a reference to the delegate object
  3. Replace all references to the delegate field with references to the given object
  4. Delete the methods with simple delegation
  5. Remove the delegate field
  6. Make sure code still works by running tests

Description

Adding delegation classes to improve class coherence.

Recipe

  1. Add a field in the subclass for holding the superclass
  2. Modify the subclass methods to make them use the superclass object
  3. Add simple delegating methods in the subclass for methods inherited from the superclass
  4. Remove the inheritance declaration
  5. Adjust the initialization code of the former superclass field by creating a delegation object
  6. Make sure code still works by running tests

Description

Removing class from hierarhy to reduce code complexity.

Recipe

  1. Select which class to remove: the superclass or subclass
  2. Use Pull Up Field and Pull Up Method or Push Down Field and Push Down Method
  3. Replace all uses of class to be removed with a class that stays
  4. Delete unnecessary empty class
  5. Make sure code still works by running tests


Sources:
Refactorings to Patterns (Joshua Kerievsky)
Refactoring Improving the Design of Existing Code (Martin Fowler)
Code Smells Catalog (Marcel Jerzyk)
Refactoring Techniques (Refactoring Guru)