При поиске SO для подходов к обработке ошибок, связанных с проверкой бизнес-правил, все, с чем я сталкиваюсь, являются примерами обработки структурированных исключений.
MSDN и многие другие авторитетные ресурсы разработки очень понятны, что исключения не используются для обработки обычных ошибок. Они могут использоваться только для исключительных обстоятельств и непредвиденных ошибок, которые могут возникнуть в результате неправильного использования программистом (но не для пользователя). Во многих случаях ошибки пользователя, такие как поля, которые остались пустыми, являются общими, и то, что наша программа должна ожидать и, следовательно, не являются исключительными, а не кандидатами на использование исключений.
Цитата:
Помните, что использование термина исключение в программировании с мыслью, что исключение должны представлять исключительную состояние. Исключительные условия: их самой природе, обычно не происходят; поэтому ваш код не должен бросать исключения как часть его повседневной операции.
Не бросайте исключения в сигнал часто встречающиеся события.. использование альтернативных методов для связи вызывающему события и оставить исключение бросать, когда что-то действительно обычного.
Например, правильное использование:
private void DoSomething(string requiredParameter)
{
if (requiredParameter == null) throw new ArgumentExpcetion("requiredParameter cannot be null");
// Remainder of method body...
}
Неправильное использование:
// Renames item to a name supplied by the user. Name must begin with an "F".
public void RenameItem(string newName)
{
// Items must have names that begin with "F"
if (!newName.StartsWith("F")) throw new RenameException("New name must begin with /"F/"");
// Remainder of method body...
}
В приведенном выше случае, в соответствии с передовыми методами, было бы лучше передать ошибку до пользовательского интерфейса без привлечения/использования механизмов обработки исключений .NET.
Используя тот же пример выше, предположим, что нужно было бы применять набор правил именования против элементов. Какой подход был бы лучше всего?
-
После возврата метода нумерованный результат? RenameResult.Success, RenameResult.TooShort, RenameResult.TooLong, RenameResult.InvalidCharacters и т.д.
-
Использование события в классе контроллера отчитываться перед классом пользовательского интерфейса? Пользовательский интерфейс вызывает контроллера RenameItem, а затем обрабатывает Событие AfterRename, которое контроллер поднимает и который переименовал статус как часть событий args?
-
Контрольный класс напрямую ссылается и вызывает метод из класса пользовательского интерфейса, который обрабатывает ошибку, например. ReportError (текст строки).
-
Что-то еще...?
По сути, я хочу знать, как выполнять сложную проверку в классах, которые могут быть не самим классом Form, и передавать ошибки обратно в класс Form для отображения, - но я не хочу включать обработку исключений, где он должен не используется (хотя это кажется намного проще!)
Основываясь на ответах на вопрос, я чувствую, что мне придется сформулировать проблему в более конкретных формулировках:
UI = Пользовательский интерфейс, BLL = Бизнес-логический уровень (в данном случае просто другой класс)
- Пользователь вводит значение в пользовательский интерфейс.
- Пользовательский интерфейс сообщает значение BLL.
- BLL выполняет рутинную проверку значения.
- BLL обнаруживает нарушение правил.
- BLL возвращает нарушение правил в пользовательский интерфейс.
- UI получает возврат от BLL и сообщает об ошибке пользователю.
Поскольку для пользователя вводятся недопустимые значения, исключения не должны использоваться. Каков правильный способ сделать это без исключений?