Проблема обработки исключений - PullRequest
0 голосов
/ 28 декабря 2010

Я заметил, что многие разработчики выполняют все виды проверок с помощью служебных классов, я имею в виду, например, SomeDefenseClass.checkState(arg > 4) и так далее.Кажется, это довольно хороший и чистый способ проверки аргументов, состояния приложения, нулевых указателей и т. Д., При этом можно вызывать только IllegalStateException для проверки состояния.NPE для нулевого указателя и так далее.Но сейчас я сталкиваюсь с проблемой: я должен выбросить много разных исключений для различных видов недопустимых состояний, например ItemNotFoundException, UserNotAuthorizedException и т. Д.

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

1) Самый простой способ: вообще не использовать служебный класс и просто писать блоки if.(Просто не хотелось бы иметь столько

if (!foo) {
    throw new SomeException(arg1); 
}
if (!bar) {
    throw new SomeOtherException(arg1, arg2);
}
// and so on

2) Чтобы написать другой метод stateCheck для каждого возможного исключения (Не очень хорошо, потому что у нас есть около 30 различных исключений и подсчет)

3) Чтобы написать один метод для класса защиты:

public static void checkState(boolean condition, Throwable t) {
    if (!condition) {
        throw t;
    }
}

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

Итак, кто-нибудь может порекомендовать хорошее решение этой проблемы?

Спасибо

Ответы [ 3 ]

3 голосов
/ 28 декабря 2010

Читая ваш первый абзац, я чувствую, что вы пытаетесь смешать бизнес-исключения (ItemNotFoundException, UserNotAuthorizedException) с утверждениями на уровне класса (проверка аргументов, состояния приложения, нулевых указателей).

Бизнес-исключения похожи на контракты с API и должны иметь значение для бизнеса, как у вас. Лучше создавать и выбрасывать их оттуда, где они принадлежат. Это не только хорошая инкапсуляция, но и СОХРАНЯЮЩАЯ правильную трассировку стека, помогая легче отладить проблему.

Утверждения в основном предназначены для внутренней логической проверки и позволяют находить логические ошибки, ошибки разработчиков и т. Д. В начале цикла тестирования, а не в процессе производства. В идеале утверждения включаются при разработке и тестировании и отключаются при производстве. Предварительные условия, Постусловия и Инварианты - это 3 вида категорий утверждений. Узнать больше о Дизайн по контракту .

Нет реальной необходимости переносить проверки утверждений в служебные методы. Запланируйте использовать встроенное в Java ключевое слово assert и включите их во время разработки и тестирования. Я предлагаю вам использовать ключевое слово assert для инвариантов и проверок постусловий и использовать Предварительные условия google-guava для проверки предварительных условий.

Если вы видите, что в разных местах выполняются общие проверки, лучше инкапсулировать их в свой собственный класс, например AgeValidator, SalaryVaidator и т. Д. (Принцип СУХОЙ). Опять же, здесь нет необходимости создавать свой собственный фреймворк, используйте стандартную спецификацию java JSR 303 Bean Validation .

1 голос
/ 28 декабря 2010

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

Моей первой мыслью было бы "сохранить исполнение контракта внутри объекта, который требует этого". Использование служебного класса обеспечивает экономию повторного использования, что ложно.

Моей второй мыслью будет структура привязки и проверки, как у Spring. Привязать входные данные из пользовательского интерфейса к объектам, проверить его и двигаться дальше. Это кажется более пригодным для повторного использования; Весна - это доказательство.

0 голосов
/ 28 декабря 2010

Рассмотрим OVal или аналогичные рамки

...