Настраиваемые исключения: дифференцировать через множество подклассов или один класс, поддерживаемый enum? - PullRequest
11 голосов
/ 14 октября 2010

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

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

В обоих случаях у меня есть:

public class MyFrameworkException   extends Exception              { /*...*/ }

Вариант 1:

public class MyProjectBaseException extends MyFrameworkException   { /*...*/ }
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ }
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ }
public class SpecificExceptionType1 extends MyProjectBaseException { /*...*/ }

Затем на протяжении всего проекта я выбрасываю конкретное исключение для любой возникающей проблемы.

Вариант 2:

public class MyProjectException extends MyFrameworkException {
  public static enum Type {
    SpecificType1, SpecificType2, SpecificType3
  }
  public MyProjectException( Type type ) { /*...*/ }
}

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

Как лучше всего обрабатывать исключения в проектах, особенно в тех, которые используют общую инфраструктуру? Являются ли два варианта выше хороших решений? Почему или почему нет? И какие есть лучшие решения?

Ответы [ 3 ]

6 голосов
/ 14 октября 2010

Главный недостаток варианта 2 (общее исключение + enum) заключается в том, что вы теряете некоторые полезности проверенных исключений. Метод в значительной степени должен просто сказать: «что-то, связанное с фреймворком, может пойти не так»:

public void foo()
throws MyFrameworkException

... вместо "x или y может пойти не так":

public void foo()
throws SomethingWentWrongException, SomethingElseWentWrongException

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

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

Редактировать И поймав точку Даффимо: я предположил, что вы говорили об исключениях, которые вы действительно должны были создать. Абсолютно выбрасывайте стандартные исключения везде, где это имеет смысл (что почти везде). Например, не создавайте свой собственный MyFrameworkIllegalArgumentException, просто используйте IllegalArgumentException (или его различные подклассы).

3 голосов
/ 14 октября 2010

Я бы пошел с исключениями, расширяющими java.lang.RuntimeException с описательными именами классов.

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

См. Совет Джошуа Блоха о в пользу стандартных исключений .

1 голос
/ 14 октября 2010

Я бы не стал наследовать от общего MyFrameworkException, если вы не предоставите никакой функциональности, общей для всех проектов.Иначе, всегда расширяйте Exception.

Обычно вы должны создавать значимые исключения на границах домена / слоя.Что касается вашего вопроса, вы должны выбрать вариант 1, имея в виду пункт выше.Вариант 2 увеличит сложность кода, так как вам всегда придется проверять тип исключения, чтобы определить, что пошло не так.Пусть класс исключения говорит сам за себя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...