Autumn SALE

Відокремлення методу

Також відомий як: Extract Method

Проблема

У вас є фрагмент коду, який можна згрупувати.

Рішення

Виділіть цей фрагмент в новий метод (чи функцію) і викличте його замість старого коду.

До
void printOwing() {
  printBanner();

  // Print details.
  System.out.println("name: " + name);
  System.out.println("amount: " + getOutstanding());
}
Після
void printOwing() {
  printBanner();
  printDetails(getOutstanding());
}

void printDetails(double outstanding) {
  System.out.println("name: " + name);
  System.out.println("amount: " + outstanding);
}
До
void PrintOwing() 
{
  this.PrintBanner();

  // Print details.
  Console.WriteLine("name: " + this.name);
  Console.WriteLine("amount: " + this.GetOutstanding());
}
Після
void PrintOwing()
{
  this.PrintBanner();
  this.PrintDetails();
}

void PrintDetails()
{
  Console.WriteLine("name: " + this.name);
  Console.WriteLine("amount: " + this.GetOutstanding());
}
До
function printOwing() {
  $this->printBanner();

  // Print details.
  print("name:  " . $this->name);
  print("amount " . $this->getOutstanding());
}
Після
function printOwing() {
  $this->printBanner();
  $this->printDetails($this->getOutstanding());
}

function printDetails($outstanding) {
  print("name:  " . $this->name);
  print("amount " . $outstanding);
}
До
def printOwing(self):
    self.printBanner()

    # print details
    print("name:", self.name)
    print("amount:", self.getOutstanding())
Після
def printOwing(self):
    self.printBanner()
    self.printDetails(self.getOutstanding())

def printDetails(self, outstanding):
    print("name:", self.name)
    print("amount:", outstanding)
До
printOwing(): void {
  printBanner();

  // Print details.
  console.log("name: " + name);
  console.log("amount: " + getOutstanding());
}
Після
printOwing(): void {
  printBanner();
  printDetails(getOutstanding());
}

printDetails(outstanding: number): void {
  console.log("name: " + name);
  console.log("amount: " + outstanding);
}

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

Чим більше коду в методі, тим складніше розібратися в тому, що він робить. Це основна проблема, яку вирішує даний рефакторинг.

Відокремлення методу не лише вбиває безліч запахів в коді, але й є одним з етапів безлічі інших рефакторингів.

Переваги

  • Покращує читабельність коду. Намагайтеся дати новому методу таку назву, яка б пояснювала суть того, що він робить. Наприклад, createOrder(), renderCustomerInfo() і так далі.

  • Прибирає дублювання коду. Іноді код, винесений в метод, можна знайти і в інших місцях програми. У такому разі є сенс замінити знайдені ділянки коду викликом вашого нового методу.

  • Ізолює незалежні частини коду, зменшуючи ймовірність помилок (наприклад, з вини перепризначення не тієї змінної).

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

  1. Створіть новий метод. Потурбуйтеся, щоб його назва відбивала суть того, що робитиме цей метод.

  2. Скопіюйте фрагмент коду, що вас цікавить, в новий метод. Видаліть цей фрагмент із старого місця і замініть викликом вашого нового методу.

    Знайдіть усі змінні, які використовувалися в цьому фрагменті коду. Якщо вони були оголошені всередині цього фрагменту і не використовуються поза ним, просто залиште їх без змін — вони стануть локальними змінними нового методу.

  3. Якщо змінні оголошені перед ділянкою коду, що вас цікавить, значить, їх слід передати в параметри вашого нового методу, щоб використати значення, які в них знаходилися раніше. Іноді від таких змінних простіше позбутися за допомогою заміни змінних викликом методу

  4. Якщо ви бачите, що локальна змінна якось змінюється у вашій ділянці коду, це може означати, що її змінене значення знадобиться далі в основному методі. Перевірте це. Якщо підозра підтвердилася, значення цієї змінної слід повернути в основний метод, щоб нічого не зламати.