Заміна коду помилки виключенням
Проблема
Метод повертає певне значення, яке сигналізуватиме про помилку.
Рішення
Замість цього слід викидати виключення.
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
).