Также известен как 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() 
{
  PrintBanner();

  //print details
  Console.WriteLine("name: " + name);
  Console.WriteLine("amount: " + GetOutstanding());
}
После
void PrintOwing()
{
  PrintBanner();
  PrintDetails(GetOutstanding());
}

void PrintDetails(double outstanding)
{
  Console.WriteLine("name: " + name);
  Console.WriteLine("amount: " + outstanding);
}
До
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)

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

Чем больше строк кода в методе, тем сложнее разобраться в том, что он делает. Это основная проблема, которую решает этот рефакторинг.

Извлечение метода не только убивает множество запашков в коде, но и является одним из этапов множества других рефакторингов.

Достоинства

  • Улучшает читабельность кода. Постарайтесь дать новому методу название, которое бы отражало суть того, что он делает. Например, createOrder(), renderCustomerInfo() и т.д.

  • Убирает дублирование кода. Иногда код, вынесенный в метод, можно найти и в других местах программы. В таком случае, имеет смысл заменить найденные участки кода вызовом вашего нового метода.

  • Изолирует независимые части кода, уменьшая вероятность ошибок (например, по вине переопределения не той переменной).

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

  1. Создайте новый метод и назовите его так, чтобы название отражало суть того, что будет делать этот метод.

  2. Скопируйте беспокоящий вас фрагмент кода в новый метод. Удалите этот фрагмент из старого места и замените вызовом вашего нового метода.

Найдите все переменные, которые использовались в этом фрагменте кода. Если они были объявлены внутри этого фрагмента и не используются вне его, просто оставьте их без изменений — они станут локальными переменными нового метода.

  1. Если переменные объявлены перед интересующим вас участком кода, значит, их следует передать в параметры вашего нового метода, чтобы использовать значения, которые в них находились ранее. Иногда от таких переменных проще избавиться с помощью замены переменных вызовом метода.

  2. Если вы видите, что локальная переменная как-то изменяется в вашем участке кода, это может означать, что её изменённое значение понадобится дальше в основном методе. Проверьте это. Если подозрение подтвердилось, значение этой переменной следует возвратить в основной метод, чтобы ничего не сломать.

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

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

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

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

Живой пример

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

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

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