
Коллега прислал письмо с кодом, с которым у него возникли трудности. Он пытается избежать использования try/catch
для управления бизнес-логикой.
Проблема не в try/catch
- это просто симптом проблемы. Можете ли вы заметить проблему? Вам придется сделать некоторые предположения, но я верю, что вы придете к тому же выводу, к которому пришел я.
Код приведен ниже; я изменил его, чтобы защитить невиновных:
private Customer GetOrCreateCustomer(long customerTelephoneNumberOrCustomerId)
{
Customer customer;
try
{
customer = this.DoMagic(customerMasterTelephoneNumberOrCustomerId);
}
catch (DataException)
{
try
{
//TODO: I know this isn't ideal. Still thinking of a better way to do this.
customer = this. GetCustomer(customerMasterTelephoneNumberOrCustomerId);
}
catch (DataException)
{
customer = this.GetCustomerFromExternal(customerMasterTelephoneNumberOrCustomerId);
customer.CustomerId = this.CreateCustomer(customer);
}
}
return customer;
}
В этой системе существует основополагающая философия, что null-значения плохи. В большинстве случаев, где может быть сгенерировано null-значение, выбрасывается исключение. Поначалу я не видел в этом проблемы. Я рассматривал это как архитектурное решение, эстетику, но по мере взаимодействия с кодом мне стало очевидно, что это архитектурная ошибка.
Вы можете спросить, почему выбрасывание исключения в случае null-значений плохо?
Ниже приведены некоторые рекомендации при рассмотрении выбрасывания исключения:
- Тот факт, что вам нужно проверять null-значение для выбрасывания исключения, должен подсказать, что это не нужно. Это ожидаемый результат, следовательно, не исключение.
- Выбрасывание исключения - это ресурсоемкая операция, одна из самых ресурсоемких операций, которые можно выполнить в .Net.
Исключение
- это именно то, что оно означает, исключение. Это исключение из предположений, сделанных в коде - когда эти предположения нарушаются, система должна завершиться, она не может продолжать, потому что система находится в неизвестном состоянии (например, база данных больше недоступна), это также может быть вектором атаки.- Выбрасывание исключения означает, что вам нужно обернуть вышестоящий вызов в блок
try/catch
для применения бизнес-правил. Null-значение - это бизнес-возможность для управления потоком приложения. Действие с null-значением должно выполняться в точке, где должно быть принято бизнес-решение. Например, переменная customer равна null, на уровне UI пользователю показывается сообщение о том, что клиент с id ‘1234’ не может быть найден.
Автор: Чак Конвей специализируется на разработке программного обеспечения и генеративном ИИ. Свяжитесь с ним в социальных сетях: X (@chuckconway) или посетите его на YouTube.