Коллега отправил письмо с кодом, с которым он борется. Он пытается избежать использования try/catches для управления бизнес-логикой.
Проблема не в try/catches, это просто симптом проблемы. Вы можете заметить проблему? Вам придется сделать некоторые предположения, но я уверен, что вы придете к тому же выводу, что и я.
Код приведен ниже; я изменил его, чтобы защитить невинных:
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;
}
В этой системе заложена основополагающая философия, что нулевые значения — это плохо. В большинстве случаев, когда может быть сгенерировано нулевое значение, выбрасывается исключение. Сначала я не видел в этом проблемы. Я рассматривал это как архитектурное решение, как эстетику, но по мере взаимодействия с кодом мне стало ясно, что это архитектурная ошибка.
Вы можете спросить, почему выброс исключения в случае нулевых значений — это плохо?
Ниже приведены некоторые рекомендации при рассмотрении выброса исключения:
- Тот факт, что вы должны проверить нулевое значение, чтобы выбросить исключение, должен быть подсказкой, что оно не требуется. Это ожидаемый результат, а не исключение.
- Выброс исключения — это ресурсоемкая операция, одна из наиболее ресурсоемких операций, которые можно выполнить в .Net.
Исключение— это именно то, что оно есть, исключение. Это исключение из предположений, сделанных в коде — когда эти предположения нарушаются, система должна завершиться, она не может продолжить работу, потому что система находится в неизвестном состоянии (например, база данных больше недоступна). Это также может быть вектором атаки.- Выброс исключения означает, что вы должны обернуть вышестоящий вызов в блок
try/catch, чтобы обеспечить соблюдение бизнес-правил. Нулевое значение — это бизнес-возможность контролировать поток приложения. Действие при нулевом значении должно быть выполнено в точке, где должно быть принято бизнес-решение. Например, переменная customer имеет нулевое значение, на уровне пользовательского интерфейса пользователю показывается сообщение о том, что клиент с идентификатором ‘1234’ не найден.
Автор: Chuck Conway — инженер AI с почти 30-летним опытом разработки программного обеспечения. Он создает практические системы AI — конвейеры контента, агенты инфраструктуры и инструменты, которые решают реальные проблемы — и делится тем, что он узнает на этом пути. Свяжитесь с ним в социальных сетях: X (@chuckconway) или посетите его на YouTube и на SubStack.