Также известен как Replace Temp with Query

Рефакторинг Замена переменной вызовом метода

Проблема

Вы помещаете результат какого-то выражения в локальную переменную, чтобы использовать её далее в коде.

Решение

Выделите все выражение в отдельный метод и возвращайте результат из него. Замените использование вашей переменной вызовом метода. Новый метод может быть использован и в других методах.
До
double calculateTotal() {
  double basePrice = quantity * itemPrice;
  if (basePrice > 1000) {
    return basePrice * 0.95;
  }
  else {
    return basePrice * 0.98;
  }
}
После
double calculateTotal() {
  if (basePrice() > 1000) {
    return basePrice() * 0.95;
  }
  else {
    return basePrice() * 0.98;
  }
}
double basePrice() {
  return quantity * itemPrice;
}
До
double CalculateTotal() 
{
  double basePrice = quantity * itemPrice;
  
  if (basePrice > 1000) 
  {
    return basePrice * 0.95;
  }
  else 
  {
    return basePrice * 0.98;
  }
}
После
double CalculateTotal() 
{
  if (BasePrice() > 1000) 
  {
    return BasePrice() * 0.95;
  }
  else 
  {
    return BasePrice() * 0.98;
  }
}
double BasePrice() 
{
  return quantity * itemPrice;
}
До
$basePrice = $this->quantity * $this->itemPrice;
if ($basePrice > 1000)
  return $basePrice * 0.95;
else
  return $basePrice * 0.98;
После
if ($this->basePrice() > 1000)
  return $this->basePrice() * 0.95;
else
  return $this->basePrice() * 0.98;

...

function basePrice() {
  return $this->quantity * $this->itemPrice;
}
До
def calculateTotal():
    basePrice = quantity * itemPrice
    if basePrice > 1000:
        return basePrice * 0.95
    else:
        return basePrice * 0.98
После
def calculateTotal():
    if basePrice() > 1000:
        return basePrice() * 0.95
    else:
        return basePrice() * 0.98

def basePrice():
    return quantity * itemPrice

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

Применение данного рефакторинга может быть подготовительным этапом для применения выделения метода для какой-то части очень длинного метода.

Кроме того, иногда можно найти это же выражение и в других методах, что заставляет задуматься о создании общего метода для его получения.

Достоинства

  • Улучшает читабельность кода. Намного проще понять, что делает метод getTax() чем строка orderPrice() * -2.

  • Помогает убрать дублирование кода, если заменяемая строка используется более чем в одном методе.

Полезные факты

Вопрос производительности

При использовании этого рефакторинга может возникнуть вопрос, не скажется ли результат рефакторинга не лучшим образом на производительности программы. Честный ответ — да, результирующий код может получить дополнительную нагрузку за счёт вызова нового метода. Однако в наше время быстрых процессоров и хороших компиляторов такая нагрузка вряд ли будет заметна. Зато взамен мы получаем лучшую читабельность кода и возможность использовать новый метод в других местах программы.

Тем не менее, если ваша временная переменная служит для кеширования результата действительно трудоёмкого выражения, имеет смысл остановить этот рефакторинг после выделения выражения в новый метод.

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

  1. Убедитесь, что переменной в пределах метода присваивается значение только один раз. Если это не так, используйте «разделение переменной» (Split temporary variable) для того, чтобы гарантировать, что переменная будет использована только для хранения результата вашего выражения.

  2. Используйте извлечение метода для того, чтобы переместить интересующее вас выражение в новый метод. Убедитесь, что этот метод только возвращает значение и не меняет состояние объекта. Если он как-то влияет на видимое состояние объекта, используйте разделение запроса и модификатора.

  3. Замените использование переменной вызовом вашего нового метода.

Устали читать?

Сбегайте за подушкой, у нас тут контента на 7 часов чтения.

Или попробуйте наш новый интерактивный курс по рефакторингу. Он более информативный и гораздо более интересный, чем банальный текст.

Узнать больше...

Живой пример

Первый раз здесь? Ничего страшного!

У нас здесь всё просто – интерактивный пример очень похож на видео (но выглядит гораздо круче).

  1. После начала проигрывания, вам показываются разнообразные подсказки и сообщения. Вы продвигаетесь дальше, кликая на них.
  2. Вы можете перематывать шаги, используя стрелки слева.
  3. Кроме того, вы можете посмотреть разницу между первоначальным и получившимся кодом, нажав кнопку с глазом ().
  4. Кнопка компиляции () позвоялет проверить текущий код на наличие ошибок.