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

Рефакторинг Відокремлення змінної

Проблема

У вас є складний для розуміння вираз.

Рішення

Помістіть результат виразу або його частини в окремі змінні, що пояснюють суть виразу.
До
void renderBanner() {
  if ((platform.toUpperCase().indexOf("MAC") > -1) &&
       (browser.toUpperCase().indexOf("IE") > -1) &&
        wasInitialized() && resize > 0 )
  {
    // do something
  }
}
Після
void renderBanner() {
  final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1;
  final boolean isIE = browser.toUpperCase().indexOf("IE") > -1;
  final boolean wasResized = resize > 0;

  if (isMacOs && isIE && wasInitialized() && wasResized) {
    // do something
  }
}
До
void RenderBanner() 
{
  if ((platform.ToUpper().IndexOf("MAC") > -1) &&
       (browser.ToUpper().IndexOf("IE") > -1) &&
        wasInitialized() && resize > 0 )
  {
    // do something
  }
}
Після
void RenderBanner() 
{
  readonly bool isMacOs = platform.ToUpper().IndexOf("MAC") > -1;
  readonly bool isIE = browser.ToUpper().IndexOf("IE") > -1;
  readonly bool wasResized = resize > 0;

  if (isMacOs && isIE && wasInitialized() && wasResized) 
  {
    // do something
  }
}
До
if (($platform->toUpperCase()->indexOf("MAC") > -1) &&
     ($browser->toUpperCase()->indexOf("IE") > -1) &&
      $this->wasInitialized() && $this->resize > 0 )
{
  // do something
}
Після
$isMacOs = $platform->toUpperCase()->indexOf("MAC") > -1;
$isIE = $browser->toUpperCase()->indexOf("IE")  > -1;
$wasResized = $this->resize > 0;

if ($isMacOs && $isIE && $this->wasInitialized() && $wasResized) {
  // do something
}
До
def renderBanner(self):
    if (self.platform.toUpperCase().indexOf("MAC") > -1) and \
       (self.browser.toUpperCase().indexOf("IE") > -1) and \
       self.wasInitialized() and (self.resize > 0):
        # do something
Після
def renderBanner(self):
    isMacOs = self.platform.toUpperCase().indexOf("MAC") > -1
    isIE = self.browser.toUpperCase().indexOf("IE") > -1
    wasResized = self.resize > 0

    if isMacOs and isIE and self.wasInitialized() and wasResized:
        # do something

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

Головна мотивація цього рефакторингу - зробити зрозумілішим складний вираз, розбивши його на проміжні частини.

Це може бути:

  • Умова оператора if () або частини оператора ?: у C-подібних мовах.
  • Довгий арифметичний вираз без проміжних результатів.
  • Довге склеювання рядків.

Виділення змінної може стати першим кроком до подальшого «відокремлення методу» (Extract method), якщо ви побачите, що виділений вираз використовується і в інших місцях коду.

Переваги

  • Покращує читабельність коду. Намагайтеся дати виділеним змінним хороші назви, які точно відображатимуть суть виразу. Так ви зробите код читабельним і зможете позбавитися від зайвих коментарів. Наприклад, customerTaxValue, cityUnemploymentRate, clientSalutationString і так далі.

Недоліки

  • З'являються додаткові змінні. Але цей мінус компенсується простотою читання коду.

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

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

  2. Замініть частину винесеного виразу новою змінною.

  3. Повторіть це для всіх складних частин виразу.

Замучились читати?

Збігайте за подушкою, в нас тут контенту приблизно на 7 годин читання.

Або спробуйте наш новий інтерактивний курс з рефакторингу. Він більш інформативний та набагато цікавіший за банальний тест.

Дізнатися більше...

Живий приклад

Перший раз у нас? Нічого страшного!

У нас тут все просто – цей інтерактивний приклад дуже схожий на відео (хоча й виглядає набагато крутіше).

  1. Натискаєте велику кнопку "Почати", а далі слідуєте усім підказкам.
  2. Ви можете перемотувати програвання, використовуючи стрілки зліва.
  3. Окрім того, ви можете подивитися різницю між стартовим та отриманим кодом, натиснувши кнопку ока ().
  4. Кнопка компіляції та тестування () дає змогу перевірити код на наявність помилок.