Я знаю два подхода к обработке исключений, давайте посмотрим на них.
-
Контрактный подход.
Когда метод не делает то, что он говорит, что он будет делать в заголовке метода, он выдает исключение. Таким образом, метод "promises", что он выполнит операцию, и если он по какой-то причине сработает, он выдаст исключение.
-
Исключительный подход.
Бросьте исключения только тогда, когда произойдет что-то действительно странное. Вы не должны использовать исключения, когда можете разрешить ситуацию с помощью обычного потока управления (операторы if). Вы не используете Исключения для потока управления, как вы могли бы в подходе к контракту.
Давайте используем оба подхода в разных случаях:
У нас есть класс Customer, который имеет метод OrderProduct.
контрактный подход:
class Customer
{
public void OrderProduct(Product product)
{
if((m_credit - product.Price) < 0)
throw new NoCreditException("Not enough credit!");
// do stuff
}
}
исключительный подход:
class Customer
{
public bool OrderProduct(Product product)
{
if((m_credit - product.Price) < 0)
return false;
// do stuff
return true;
}
}
if !(customer.OrderProduct(product))
Console.WriteLine("Not enough credit!");
else
// go on with your life
Здесь я предпочитаю исключительный подход, так как это действительно не Исключительно, что у клиента нет денег, полагая, что он не выиграл в лотерею.
Но вот ситуация, в которой я ошибаюсь в стиле контракта.
Исключительный:
class CarController
{
// returns null if car creation failed.
public Car CreateCar(string model)
{
// something went wrong, wrong model
return null;
}
}
Когда я вызываю метод под названием CreateCar, я чертовски приветствую экземпляр Car вместо какого-то паршивого нулевого указателя, который позже может разрушить мой текущий код. Поэтому я предпочитаю контракт с этим:
class CarController
{
public Car CreateCar(string model)
{
// something went wrong, wrong model
throw new CarModelNotKnownException("Model unkown");
return new Car();
}
}
Какой стиль вы используете? Как вы думаете, лучший ли общий подход к Исключениям?