Вместо использования исключений я склонен возвращать список объектов состояния из методов, которые могут иметь проблемы при выполнении. Объекты состояния содержат перечисление серьезности (информация, предупреждение, ошибка, ...), имя объекта состояния, например «Адрес электронной почты», и читаемое пользователем сообщение, например «Плохо отформатированный адрес электронной почты»
Затем вызывающий код решает, какой фильтровать до пользовательского интерфейса, а какой обрабатывать сам.
Лично я думаю, что исключения исключительно для случаев, когда вы не можете реализовать нормальное кодовое решение. Падение производительности и ограничения на обработку для меня слишком велики.
Другая причина использования списка объектов состояния заключается в том, что намного проще выявить несколько ошибок (например, во время проверки). В конце концов, вы можете бросить только одно исключение, которое должно быть обработано, прежде чем двигаться дальше.
Представьте себе пользователя, отправляющего электронное письмо с неверно сформированным адресом назначения и языком, который вы блокируете. Вы сгенерируете исключение из-за неверно сформированной электронной почты, а затем, после того, как они исправят это и повторно отправят, сгенерирует исключение на плохом языке? С точки зрения пользовательского опыта, лучше всего разобраться со всеми ими одновременно.
ОБНОВЛЕНИЕ: объединение ответов
@ Джонатан: Моя точка зрения заключалась в том, что я могу оценить действие, в данном случае отправить электронное письмо, и отправить обратно несколько причин сбоя. Например, «неверный адрес электронной почты», «пустой заголовок сообщения» и т. Д.
За исключением, вы ограничены только тем, что просите одну проблему, а затем попросите пользователя повторно отправить сообщение, после чего он узнает о второй проблеме. Это действительно плохой дизайн пользовательского интерфейса.
Изобретая колесо .. возможно. Однако большинство приложений должны анализировать всю транзакцию, чтобы предоставить пользователю наилучшую информацию. Представьте, что ваш компилятор остановился при первой ошибке. Затем вы исправляете ошибку и снова нажимаете на compile, чтобы снова остановить ее для другой ошибки. Какая боль в заднице. Для меня это как раз проблема с генерацией исключений и, следовательно, причина, по которой я сказал использовать другой механизм.