Category
Simplifying Method Calls
Techniques that clean up method signatures, names, parameters and error signaling so interfaces are hard to call incorrectly.
What these techniques solve
A method's signature is its contract with every caller. Unclear names, long or redundant parameter lists, methods that both return a value and change state, setters on objects that should be fixed, and error codes returned as numbers all invite misuse of that contract. These techniques change the interface rather than the body.
Signature changes touch every caller. Find them all first, and keep the old signature as a forwarding wrapper until the last one is migrated if the method is public.
Members
- Rename Method: give a method a name that says what it does.
- Add Parameter: pass in data the method now needs instead of reaching for it some other way.
- Remove Parameter: drop a parameter the body no longer uses.
- Separate Query from Modifier: split a method that returns a value and changes state into two methods.
- Parameterize Method: merge near-identical methods that differ only in a value into one method with a parameter.
- Replace Parameter with Explicit Methods: split a method that switches on a parameter into one method per case.
- Preserve Whole Object: pass the object instead of several values pulled out of it.
- Replace Parameter with Method Call: let the method get a value itself instead of every caller computing and passing it.
- Introduce Parameter Object: group parameters that always travel together into one object.
- Remove Setting Method: delete a setter for a field that should only be set at construction.
- Hide Method: make a method private or internal when no outside code needs it.
- Replace Constructor with Factory Method: create objects through a named function that can choose a subtype or reuse instances.
- Replace Error Code with Exception: signal failure with an exception rather than a special return value.
- Replace Exception with Test: check a condition up front instead of catching an exception for an expected case.
How to choose within this category
- The name lies or is vague: Rename Method. Do this first; it is the cheapest, highest-value change here. Use your IDE or language server rename so all callers update.
- Too many parameters: if they come from one object, Preserve Whole Object. If they always travel together, Introduce Parameter Object. If the method could compute one itself, Replace Parameter with Method Call.
- Near-duplicate methods vs a flag parameter: these are inverses. Merge with Parameterize Method when the parameter is a value (a rate, a limit). Split with Replace Parameter with Explicit Methods when it is a mode or boolean that picks different behavior.
- A getter has side effects: Separate Query from Modifier.
- An object should be immutable after creation: Remove Setting Method. Records,
readonlyfields and frozen dataclasses make this a declaration. - The public surface is larger than its use: Hide Method, and Remove Parameter for unused inputs. Check reflection, serialization and other packages before shrinking a public API.
- Constructors can't express intent or choose a subtype: Replace Constructor with Factory Method.
- Error signaling: follow your language's convention. Use Replace Error Code with Exception in exception-based languages. In Go and Rust, return
errororResultinstead; a numeric code is still the smell, but an exception is not the cure. Use Replace Exception with Test when the "exceptional" case is routine and cheap to check.
In this category
See also
- Composing MethodsTechniques that split, merge and reshape method bodies so each method does one readable thing and local variables stop blocking change.
- Organizing DataTechniques that turn raw fields, magic values, arrays and type codes into objects and types that carry meaning and protect their own invariants.
- Long Parameter ListA function takes so many parameters that callers mix up their order and every new option changes every call site.
- Data ClumpsThe same group of variables travels together through fields and parameters, signaling a missing object that should own them.
Original writing and examples. Topic coverage follows Refactoring.Guru, which explains this topic with its own illustrations.