Refactoring techniques
Composing Methods
9 entriesTechniques that split, merge and reshape method bodies so each method does one readable thing and local variables stop blocking change.
- Extract MethodMove a coherent fragment of a long function into its own well-named function and call it from the original place.
- Inline MethodReplace calls to a function whose body is as clear as its name with the body itself, then delete the function.
- Extract VariableName a hard-to-read expression or sub-expression by assigning it to a well-named local variable.
- Inline TempReplace a temporary variable that holds a simple expression with the expression itself when the name adds nothing.
- Replace Temp with QueryMove the expression behind a temporary variable into its own method so every method in the class can ask for the value.
- Split Temporary VariableGive each distinct purpose its own variable when one local is reassigned to hold unrelated intermediate values.
- Remove Assignments to ParametersStop reassigning a function parameter inside its body; copy it into a local variable and work on that instead.
- Replace Method with Method ObjectTurn a long method with tangled local variables into its own class, so the locals become fields and the body can be split freely.
- Substitute AlgorithmReplace the body of a function with a clearer or simpler algorithm that produces the same results.
Moving Features between Objects
8 entriesTechniques that relocate methods, fields and whole classes so each responsibility lives next to the data it uses.
- Move MethodMove a method to the class whose data it uses most, and leave a delegating call or update the callers.
- Move FieldMove a field to the class that uses it most, updating every reader and writer to reach it there.
- Extract ClassSplit a class that does two jobs by moving one job's fields and methods into a new class it holds a reference to.
- Inline ClassFold a class that does too little into the class that uses it, moving its fields and methods across and deleting it.
- Hide DelegateAdd a method on the server object that forwards to its delegate, so clients stop navigating through it to reach the delegate.
- Remove Middle ManLet clients call the delegate directly when a class does little more than forward calls to it.
- Introduce Foreign MethodAdd a helper in your own code that takes an instance of a class you cannot change and provides the method it lacks.
- Introduce Local ExtensionWrap or subclass a class you cannot change in your own class that adds the methods you need.
Organizing Data
15 entriesTechniques that turn raw fields, magic values, arrays and type codes into objects and types that carry meaning and protect their own invariants.
- Self Encapsulate FieldAccess a field through its own getter and setter even inside the class, so subclasses or later changes can intercept the access.
- Replace Data Value with ObjectTurn a primitive field that has grown rules and companions into a small class that owns its data and behavior.
- Change Value to ReferenceReplace many identical copies of an entity with one shared instance looked up from a registry, so updates are seen everywhere.
- Change Reference to ValueMake a small shared object immutable and compare it by content, so it can be copied freely instead of tracked by identity.
- Replace Array with ObjectReplace an array whose positions hold different kinds of data with an object that has a named field for each.
- Duplicate Observed DataMove domain data out of a UI class into a domain object, and keep the UI in sync with it through observation.
- Change Unidirectional Association to BidirectionalAdd a back-reference when each of two classes needs to navigate to the other, and keep both sides in sync through one owner.
- Change Bidirectional Association to UnidirectionalRemove a back-reference that no code needs any more, so two classes stop depending on each other.
- Replace Magic Number with Symbolic ConstantGive a literal number or string with special meaning a named constant, and use the name everywhere the value appears.
- Encapsulate FieldMake a public field private and give clients accessor methods, so the class controls how its data is read and changed.
- Encapsulate CollectionStop a getter from handing out a mutable internal collection; return a read-only view and add methods to add and remove items.
- Replace Type Code with ClassReplace a set of string or number codes that don't affect behavior with a dedicated type, so only valid codes can be used.
- Replace Type Code with SubclassesTurn each value of an immutable type code that drives conditionals into a subclass, and move the branch logic into overrides.
- Replace Type Code with State/StrategyMove behavior that depends on a type code into separate state or strategy objects that the host holds and can swap at runtime.
- Replace Subclass with FieldsCollapse subclasses that differ only in the constants their methods return into fields on the parent, then delete the subclasses.
Simplifying Conditional Expressions
8 entriesTechniques that flatten, name, merge and replace conditionals so branching logic reads as a list of plain decisions.
- Decompose ConditionalMove a complex condition and each of its branches into well-named functions so the decision reads as intent instead of arithmetic.
- Consolidate Conditional ExpressionMerge a run of separate checks that all lead to the same result into one condition with a name that states the shared rule.
- Consolidate Duplicate Conditional FragmentsMove code that runs identically in every branch of a conditional to before or after the conditional so each branch holds only what differs.
- Remove Control FlagReplace a boolean variable that steers a loop or function with break, continue or return so control flow is explicit.
- Replace Nested Conditional with Guard ClausesHandle special and invalid cases first with early returns so the normal path runs flat at the end of the function.
- Replace Conditional with PolymorphismReplace a switch on an object's type or kind with one class per case that overrides a shared method, so new cases add code instead of editing it.
- Introduce Null ObjectReplace repeated null checks for a missing collaborator with an object that implements the same interface and does the safe default.
- Introduce AssertionState an assumption the code already relies on as an explicit check that fails fast, instead of leaving it in a comment or in the reader's head.
Simplifying Method Calls
15 entriesTechniques that clean up method signatures, names, parameters and error signaling so interfaces are hard to call incorrectly.
- Rename MethodChange a method's name to say what it does, using a forwarding alias when callers cannot all be updated at once.
- Add ParameterGive a method a new parameter when it needs data it cannot reach, migrating callers through a temporary overload or default value.
- Remove ParameterDelete a parameter the method body no longer uses, updating every caller and override so the signature states only real dependencies.
- Separate Query from ModifierSplit a method that both returns a value and changes state into a side-effect-free query and a separate command.
- Parameterize MethodMerge several methods that do the same thing with different literal values into one method that takes the value as a parameter.
- Replace Parameter with Explicit MethodsSplit a method that branches on a flag or enum argument into one clearly named method per value.
- Preserve Whole ObjectPass the object itself instead of several values pulled out of it, so the method signature stays stable as needs change.
- Replace Parameter with Method CallStop passing a value the method can obtain itself; have the method call the query directly and drop the parameter.
- Introduce Parameter ObjectReplace a group of parameters that always travel together with one object type, then move behavior on that group into it.
- Remove Setting MethodDelete the setter for a field that should only be set at creation, and assign it in the constructor so it cannot change later.
- Hide MethodReduce a method's visibility to private or protected when nothing outside the class needs it, shrinking the public surface.
- Replace Constructor with Factory MethodWrap object creation in a named static or module function when a plain constructor cannot express intent, pick a subtype, or reuse instances.
- Replace Error Code with ExceptionThrow a typed exception instead of returning a sentinel such as -1 or false, so failures cannot be silently ignored by callers.
- Replace Exception with TestCheck a predictable condition before the call instead of catching the exception it would throw, keeping exceptions for real failures.
- Consolidate ToolsMerge thin, overlapping tools into one task-shaped tool that returns only the fields the task reads, and describe when to use it - so consumers pick right the first time and stop chaining calls.
Dealing with Generalization
12 entriesTechniques that move members up and down class hierarchies, create or collapse hierarchies, and swap inheritance for delegation.
- Pull Up FieldMove a field that every subclass declares in the same way into their shared superclass so it is defined once.
- Pull Up MethodMove a method that is identical across subclasses into their superclass so the logic lives and changes in one place.
- Pull Up Constructor BodyMove initialization code shared by subclass constructors into a superclass constructor and call it with super().
- Push Down MethodMove a superclass method into the only subclasses that use it, so the superclass describes only what all subclasses share.
- Push Down FieldMove a superclass field into the subclasses that use it, so other subclasses stop carrying state they never touch.
- Extract SubclassMove features used only by some instances of a class into a new subclass, replacing the flag or nullable fields that marked them.
- Extract SuperclassCreate a shared superclass for two classes with overlapping fields and methods, and pull the common parts up into it.
- Extract InterfaceDeclare the subset of a class's methods that clients actually use as an interface, so clients depend on the contract instead of the class.
- Collapse HierarchyMerge a subclass into its superclass (or the reverse) when the two have become nearly identical and the split no longer earns its cost.
- Form Template MethodWhen subclass methods follow the same sequence of steps with different details, pull the sequence into the superclass and leave only the steps in subclasses.
- Replace Inheritance with DelegationTurn a subclass that uses only part of its superclass into a class that holds an instance of it and forwards just the calls it needs.
- Replace Delegation with InheritanceWhen a class forwards nearly every call to one delegate it truly is a kind of, make it a subclass of that delegate and delete the forwarding.