Specific Refactorings
How are refactorings described and organized?
Individual refactorings are a lot like individual design patterns. They are categorized by what they do. Some categories include:
- Composing Methods
- Moving Features Between Objects
- Organizing Data
- Simplifying Conditional Expressions
- Making Method Calls Simpler
- Dealing with Generalization
- Big Refactorings
Within each of these categories are many different refactorings. Its important to note that given almost any refactoring its inverse is also a refactoring. This because it is needed in a step toward something else or that too much of a good thing can be bad.
Refactorings are carefully defined, each has several important parts:
- Name - provides a vocabulary of refactoring but also of problems i.e. a situation where X refactoring is needed
- Summary - lets you know if this is what you need quickly
- Motivation - in depth about when its needed and why it should be done
- Mechanics - concise step by step instructions to performing the refactoring, including things to check for
- Example - an example of the refactoring being applied
Some refactorings
- Extract & Inline method - pull code out of a method and make another method out of it. This gives it a descriptive name and removes code duplication. The inverse is inline where we move code from one method into another therefore removing the method.
- Move Method & Field - if a field or method is in the wrong class it can be moved.
- Extract & Inline class - Just like Extract & Inline method but for classes.
- Hide delegate - Keep an a method from having to traverse another objects delegation to get the information it needs by adding a method to provide what is needed.
- Remove Middle Man - basically reverse Hide Delegate. Good when something needs lots of information from a delegate.
- Introduce Null Object - whenever one uses the raw null value a Null Object Pattern would usually work better.
- Replace Conditional with Polymorphism - many conditionals can be made clearer and less error prone by using polymorphism to achieve the same effect. This makes the objects smarter and reduces that tricky logic code.
- Rename Method - sometimes a method's name no longer matches what it is supposed to do.
- Encapsulate Downcast - if clients commonly have to downcast the return of a method move the downcast into the method to make it safer and cleaner.
- Pull Up and Down - move methods and fields up and down in the abstraction hierarchy. For example create an abstract parent method for to previously unconnected method or move code that was duplicated in multiple subclasses into a parents non abstract method.
jwalker@cs.oberlin.edu