Autumn SALE

Replace Parameter with Explicit Methods

Problem

A method is split into parts, each of which is run depending on the value of a parameter.

Solution

Extract the individual parts of the method into their own methods and call them instead of the original method.

Before
void setValue(String name, int value) { if (name.equals("height")) { height = value; return; } if (name.equals("width")) { width = value; return; } Assert.shouldNeverReachHere(); }
After
void setHeight(int arg) { height = arg; } void setWidth(int arg) { width = arg; }
Before
void SetValue(string name, int value) { if (name.Equals("height")) { height = value; return; } if (name.Equals("width")) { width = value; return; } Assert.Fail(); }
After
void SetHeight(int arg) { height = arg; } void SetWidth(int arg) { width = arg; }
Before
function setValue($name, $value) { if ($name === "height") { $this->height = $value; return; } if ($name === "width") { $this->width = $value; return; } assert("Should never reach here"); }
After
function setHeight($arg) { $this->height = $arg; } function setWidth($arg) { $this->width = $arg; }
Before
def output(self, name): if name == "banner" # Print the banner. # ... if name == "info" # Print the info. # ... 
After
def outputBanner(self): # Print the banner. # ... def outputInfo(self): # Print the info. # ...
Before
 setValue(name: string, value: number): void { if (name.equals("height")) { height = value; return; } if (name.equals("width")) { width = value; return; } }
After
setHeight(arg: number): void { height = arg; } setWidth(arg: number): number { width = arg; }

Why Refactor

A method containing parameter-dependent variants has grown massive. Non-trivial code is run in each branch and new variants are added very rarely.

Benefits

  • Improves code readability. It’s much easier to understand the purpose of startEngine() than setValue("engineEnabled", true).

When Not to Use

  • Don’t replace a parameter with explicit methods if a method is rarely changed and new variants aren’t added inside it.

How to Refactor

  1. For each variant of the method, create a separate method. Run these methods based on the value of a parameter in the main method.

  2. Find all places where the original method is called. In these places, place a call for one of the new parameter-dependent variants.

  3. When no calls to the original method remain, delete it.