Предпосылки и исключения

Предположим, у вас есть метод с некоторыми предварительными и последующими условиями. Можно ли создать класс исключений для каждого невыполненного предварительного условия? Например: не выполнить pre1 означает выброс экземпляра notPre1Exception.

12 ответов

Решение

И да и нет.

Да. Нарушение предусловия, безусловно, подходящее время для исключения. Создание более специфического исключения упростит отлов этого конкретного исключения.

Нет - объявление нового класса исключений для каждого предварительного условия в вашей программе / API кажется слишком излишним. Это может привести к сотням или тысячам исключений в конечном итоге. Это кажется пустой тратой как в умственном, так и в вычислительном отношении.

Я бы рекомендовал выбрасывать исключения для нарушений предварительных условий. Однако я бы не рекомендовал определять новое исключение для каждого предварительного условия. Вместо этого я бы рекомендовал создавать более широкие классы исключений, которые охватывают определенный тип нарушения предусловия, а не конкретное нарушение предусловия. (Я бы также рекомендовал использовать существующие исключения там, где они хорошо подходят.)

Почему вы не хотите определять PreconditionFailedException(предусловие строки)? Создание другого типа исключения для каждого невыполненного условия является излишним.

Неудачное предварительное условие должно вызвать AssertException или что-то подобное. Прежде чем вызывать метод, необходимо выполнить его предварительное условие. Если вызывающая сторона не выполняет эту проверку, это ошибка в программе или неправильное использование метода (API).

Звучит как полезное использование исключений для меня. Это, безусловно, позволяет более детализировать ведение журнала и отладку, чем просто общее "сбой предусловия", хотя вы также можете иметь единственное исключение "сбой предусловия" и поместить то, что предусловия не выполнили, в сообщение об исключении.

В качестве очень общего способа определения, следует ли вам когда-либо создавать класс (а исключением является класс), вы должны определить, существует ли какой-либо код, который делает этот класс уникальным среди всех других классов (в данном случае исключения).

Если нет, я бы просто установил строку в исключении и назвал бы ее днем. Если вы выполняете код в своем исключении (возможно, общий механизм восстановления, который может обрабатывать несколько ситуаций, вызывая exception.resolve() или что-то в этом роде), то это может быть полезно.

Я понимаю, что исключения не всегда следуют этому правилу, но я думаю, что это более или менее потому, что исключения, предоставляемые языком, не могут содержать бизнес-логику (потому что они не знают бизнес - библиотеки всегда имеют тенденцию полный исключений из правил ОО)

Только если не выполнение предварительных условий будет редким исключительным явлением.

Для меня это кажется возможным, но если вы хотите продолжить этот способ работы с предварительными условиями, вы получите N классов исключений для каждого метода класса. Выглядит как взрывной рост "нефункциональных" классов.

Мне всегда нравился код, в котором "базовая" функциональность не справлялась с нарушением предварительных условий (кроме их утверждения - отличная помощь!). Затем этот код может быть помещен в "средство проверки предусловий", которое генерирует исключения или иным образом уведомляет о неудовлетворенности.

Нет, вам не следует создавать отдельное исключение для каждого предварительного условия, поскольку оно будет противоречить принципам "Дизайн по контракту".

Следствия выполнения предварительных условий состоят в том, что они должны быть частью документации и что вы должны предоставить вызывающему абоненту необходимые методы для проверки того, что все предварительные условия действительны. (т. е. если выполнение метода зависит от состояния объекта, метод проверки состояния должен быть доступен вызывающей стороне).

Таким образом, вызывающая сторона должна иметь возможность проверить, выполнены ли все предварительные условия перед вызовом вашего метода.

Реализация определенных исключений для каждого нарушенного предварительного условия будет / может побудить вызывающего абонента использовать шаблон try / catch вокруг вызова метода, что противоречит философии Проектирования по контракту.

Я думаю, что Бен находится на цели здесь. Какой смысл бросать разные исключения, если вы не собираетесь их ловить? Если вы действительно хотите выбросить другой, я бы по крайней мере имел общий базовый класс "PreconditionFailedException", из которого они все происходят, и попытался бы организовать их в какую-то иерархию, чтобы вы могли поймать их группы. Лично у меня не было бы других, и у меня было бы общее исключение, которое вы выбрасываете с деталями ошибки в каждом из них.

Я думаю, что можно создать другое исключение для всех ваших исключений, если вы планируете их использовать и обрабатывать.

Я обнаружил, что чем лучше обработка ошибок / исключений, тем легче отлаживать программное обеспечение на более поздних этапах.

Например: если у вас есть общее исключение для обработки всех неверных входных данных, вы должны посмотреть на все, что было передано в метод, если есть ошибка. Если у вас есть исключения из всех типов плохих условий, вы будете точно знать, где искать.

Если вы сделаете это, убедитесь, что все они наследуются от другого общего пользовательского исключения.

Я бы сказал, что все в порядке, если вы делаете их непроверенными исключениями (подкласс RuntimeException в Java). Однако в Java лучше просто использовать утверждения.

Другие вопросы по тегам