Также известен как 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 часов чтения.

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

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