Замена кода ошибки исключением
Проблема
Метод возвращает определенное значение, которое будет сигнализировать об ошибке.
Решение
Вместо этого следует выбрасывать исключение.
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;
}
}
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:
raise BalanceException()
self.balance -= amount
withdraw(amount: number): number {
if (amount > _balance) {
return -1;
}
else {
balance -= amount;
return 0;
}
}
withdraw(amount: number): void {
if (amount > _balance) {
throw new Error();
}
balance -= amount;
}
Причины рефакторинга
Возвращение кодов ошибок — давно устаревшая практика процедурного программирования. В современном программировании для обработки ошибок используются специальные классы, называемые исключениями. При возникновении проблемы вы «выбрасываете» такое исключение и оно впоследствии «ловится» одним из обработчиков исключений. При этом запускается специальный код обработки внештатной ситуации, который игнорируется в обычных условиях.
Достоинства
-
Избавляет код от множества условных операторов проверки кодов ошибок. Обработчики исключений намного чётче разграничивают нормальный и нештатный путь исполнения программы.
-
Классы исключений могут реализовывать собственные методы, а значит содержать часть функциональности по обработке ошибок (например, для перевода сообщений об ошибках).
-
В отличие от исключений, коды ошибок не могут быть использованы в конструкторе, так как он должен возвращать только новый объект.
Недостатки
- Обработку исключений можно превратить в
goto
-подобный костыль. Не делайте так! Не используйте исключения для управления исполнением кода. Исключения следует выбрасывать только в целях сообщения об ошибке или критической ситуации.
Порядок рефакторинга
Старайтесь выполнять шаги этого рефакторинга только для одного кода ошибки за один раз. Так будет легче удержать в голове все важные сведения и избежать ошибок.
-
Найдите все вызовы метода, возвращающего код ошибки, и оберните его в
try
/catch
блоки вместо проверки кода ошибки. -
Внутри метода вместо возвращения кода ошибки выбрасывайте исключение.
-
Измените сигнатуру метода так, чтобы она содержала информацию о выбрасываемом исключении (секция
@throws
).