Також відомий як Replace Error Code with Exception

Рефакторинг Заміна коду помилки виключенням

Проблема

Метод повертає певне значення, яке сигналізуватиме про помилку.

Рішення

Замість цього слід викидати виключення.

До
int withdraw(int amount) {
  if (amount > _balance) {
    return -1;
  }
  else {
    balance -= amount;
    return 0;
  }
}
Після
void withdraw(int amount) throws BalanceException {
  if (amount > _balance) {
    throw new BalanceException();
  }
  balance -= amount;
}
До
int Withdraw(int amount) 
{
  if (amount > _balance) 
  {
    return -1;
  }
  else 
  {
    balance -= amount;
    return 0;
  }
}
Після
///<exception cref="BalanceException">Thrown when amount > _balance</exception>
void Withdraw(int amount)
{
  if (amount > _balance) 
  {
    throw new BalanceException();
  }
  balance -= amount;
}
До
function withdraw($amount) {
  if ($amount > $this->balance)
    return -1;
  else {
    $this->balance -= $amount;
    return 0;
  }
}
Після
/**
 * (Here you put some real function documentation.
 *  Note: the line below indicates that function
 *  can throw an exception of given type.)
 * @throws BalanceException
 */
function withdraw($amount) {
  if ($amount > $this->balance) {
    throw new BalanceException();
  }
  $this->balance -= $amount;
}
До
def withdraw(self, amount):
    if amount > self.balance:
        return -1
    else:
        self.balance -= amount
    return 0
Після
def withdraw(self, amount):
    if amount > self.balance:
        raize BalanceException()
    self.balance -= amount

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

Повернення кодів помилок - давно застаріла практика процедурного програмування. У сучасному програмуванні для обробки помилок використовуються спеціальні класи, що називаються виключеннями. При виникненні проблеми ви «викидаєте» таке виключення і воно згодом "ловиться" одним з обробників виключень. При цьому запускається спеціальний код обробки позаштатної ситуації, який ігнорується в звичайних умовах.

Переваги

  • Позбавляє код від безлічі умовних операторів перевірки кодів помилок. Обробники виключень набагато чіткіше розмежовують нормальний і нештатний шлях виконання програми.

  • Класи виключень можуть реалізовувати власні методи, а значить містити частину функціональності по обробці помилок (наприклад, для перекладу повідомлень про помилки).

  • На відміну від виключень, коди помилок не можуть бути використані в конструкторі, оскільки він повинен повертати тільки новий об'єкт.

Недоліки

  • Обробку виключень можна перетворити на goto-подібний костиль. Не робіть так! Не використовуйте виключення для управління виконанням коду. Виключення слід викидати тільки в цілях повідомлення про помилку або критичну ситуацію.

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

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

  1. Знайдіть усі виклики методу, що повертає код помилки, і оберніть його в try/catch блоки замість перевірки коду помилки.

  2. Усередині методу замість повернення коду помилки викидайте виключення.

  3. Змініть сигнатуру методу так, щоб вона містила інформацію про виключення, що викидається (секція @throws).

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

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

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

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