Autumn SALE

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

Також відомий як: 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, type):
    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. Коли не залишиться жодного виклику оригінального методу, його можна буде видалити.