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

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

Проблема

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

Рішення

Замініть викидання виключення перевіркою цієї умови.
До
double getValueForPeriod(int periodNumber) {
  try {
    return values[periodNumber];
  } catch (ArrayIndexOutOfBoundsException e) {
    return 0;
  }
}
Після
double getValueForPeriod(int periodNumber) {
  if (periodNumber >= values.length) {
    return 0;
  }
  return values[periodNumber];
}
До
double GetValueForPeriod(int periodNumber) 
{
  try 
  {
    return values[periodNumber];
  } 
  catch (IndexOutOfRangeException e) 
  {
    return 0;
  }
}
Після
double GetValueForPeriod(int periodNumber) 
{
  if (periodNumber >= values.Length) 
  {
    return 0;
  }
  return values[periodNumber];
}
До
function getValueForPeriod($periodNumber) {
  try {
    return $this->values[$periodNumber];
  } catch (ArrayIndexOutOfBoundsException $e) {
    return 0;
  }
}
Після
function getValueForPeriod($periodNumber) {
  if ($periodNumber >= count($this->values)) {
    return 0;
  }
  return $this->values[$periodNumber];
}
До
def getValueForPeriod(periodNumber):
    try:
        return values[periodNumber]
    except IndexError:
        return 0
Після
def getValueForPeriod(self, periodNumber):
    if periodNumber >= len(self.values):
        return 0
    return self.values[periodNumber]

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

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

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

Переваги

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

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

  1. Створіть умовний оператор для граничного випадку і розташуйте його перед try/catch блоком.

  2. Перемістіть код з catch-секції всередину цього умовного оператора.

  3. У catch-секції розташцуйте код викидання звичайного безіменного виключення і запустіть усі тести.

  4. Якщо ніяких виключень не було викинуто під час тестів, позбавтеся від оператора try/catch.

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

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

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

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

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

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

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

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