Friend spotlight!
Whimsical Animations course
Friend spotlight!
NEW Whimsical Animations course
Friend spotlight! NEW Whimsical Animations course
huge discount only this week
Friend spotlight! Want to make your project stand out? NEW Whimsical Animations course huge discount only this week

Заміна параметра набором спеціалізованих методів

Також відомий як: Replace Parameter with Explicit Methods

Проблема

Метод було розбито на частини, кожна з яких виконується залежно від значення якогось параметра.

Рішення

Витягніть окремі частини методу у власні методи і викликайте їх замість оригінального методу.

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

def outputInfo(self):
    # Print the info.
    # ...
До
 setValue(name: string, value: number): void {
  if (name.equals("height")) {
    height = value;
    return;
  }
  if (name.equals("width")) {
    width = value;
    return;
  }
  
}
Після
setHeight(arg: number): void {
  height = arg;
}
setWidth(arg: number): number {
  width = arg;
}

Причини рефакторингу

Метод, що містить варіанти виконання, розрісся до грандіозних розмірів. У кожному з таких ланцюжків виконується нетривіальний код. При цьому нові варіанти додаються дуже рідко.

Переваги

  • Покращує читабельність коду. Куди очевидніше, що робить метод startEngine(), ніж setValue("engineEnabled", true).

Коли не слід застосовувати

  • Не варто застосовувати заміну параметра явними методами, якщо метод рідко міняється, а нові варіації усередині нього не додаються.

Порядок рефакторингу

  1. Для кожного варіанту виконання методу створіть свій власний метод. Запускайте ці методи залежно від значення параметра в основному методі.

  2. Знайдіть усі місця, де викликається оригінальний метод. Підставте туди виклик одного з нових методів залежно від параметра, що передається.

  3. Коли не залишиться жодного виклику оригінального методу, його можна буде видалити.