Имейте в виду, что цель Реагента состоит в том, чтобы лучше сочетать вещи, которые логически должны быть связаны. Если вы разрабатываете сложный метод «проверки пароля», где его следует связывать?
Ну, вам нужно будет использовать его каждый раз, когда пользователю нужно ввести новый пароль. Это может быть на экране регистрации, экране «забытый пароль», экране администратора «Сбросить пароль для другого пользователя» и т. Д.
. Но в любом из этих случаев он всегда будет привязан к некоторым текстовое поле ввода. Таким образом, это должно быть связано.
Создайте очень маленький компонент React, который состоит исключительно из поля ввода и связанной логики проверки. Введите этот компонент во все формы, которые могут потребовать ввода пароля.
По сути, это тот же результат, что и для службы / фабрики для логики, но вы связываете его непосредственно со входом. Таким образом, вам теперь не нужно указывать эту функцию, где искать вход для проверки, поскольку он постоянно связан.
Я бы сказал, что это действительно плохая идея. Большая часть кода реализована в предположении, что если вы поймаете Ошибка
и Исключение
, вы поймаете все возможные исключения. И большинство учебных пособий и учебников расскажут вам то же самое. Создавая прямой подкласс Throwable
, вы потенциально создаете всевозможные проблемы обслуживания и взаимодействия.
Я не могу придумать веских причин для расширения Throwable
. Вместо этого расширьте Exception
или RuntimeException
.
РЕДАКТИРОВАТЬ - В ответ на предложенный OP сценарий №1.
Исключения - очень дорогой способ борьбы с «нормальным» управлением потоком. В некоторых случаях речь идет о тысячах дополнительных инструкций, выполняемых для создания, генерирования и перехвата исключения. Если вы собираетесь игнорировать общепринятую мудрость и использовать исключения для неисключительного управления потоком, используйте подтип Exception
. Попытка сделать вид, что что-то является «событием», а не «исключением», объявив это как подтип Throwable
, ничего не даст.
Однако ошибочно объединять исключение с ошибкой, ошибкой, ошибкой и т. Д. И нет ничего неправильного в представлении «исключительного события, которое не является ошибкой, ошибкой или чем-то еще» с использованием подкласса Exception
. Ключ в том, что событие должно быть исключительным ; т.е. необычно, случается очень редко, ...
Таким образом, FlyingPig
не может быть ошибкой, но это не причина не объявлять его как подтип Exception
.
Является ли этот метод (ab) с использованием исключения допустимым? (Есть ли для него название?)
На мой взгляд, это не очень хорошая идея:
Исключение не следует просто использовать для управления потоком . Если бы мне пришлось назвать эту технику, я бы назвал это запахом кода или анти-паттерном.
См. Также:
Если допустимо, следует
FlyingPig
расширяетThrowable
, илиException
просто отлично? (хотя в его обстоятельствах нет ничего исключительного?)
Могут быть ситуации, когда вы хотите поймать Throwable
, чтобы не только поймать Exception
, но и Error
но это редко, люди обычно не ловят Throwable
. Но мне не удается найти ситуацию, в которой вы хотели бы выбросить подкласс Throwable
.
И я также думаю, что расширение Throwable
не делает вещи выглядящими менее «исключительными» , они заставляют его выглядеть хуже - что полностью противоречит намерению.
Итак, в заключение, если вы действительно хотите что-то бросить, бросьте подкласс Exception
.
См. Также:
По мере того, как этот вопрос развивался, я вижу, что неправильно понял смысл первоначального вопроса, поэтому некоторые другие ответы, вероятно, более актуальны. Я оставлю этот ответ здесь, так как он все еще может быть полезен для других, у которых есть подобный вопрос, и найти эту страницу во время поиска ответа на свой вопрос.
Нет ничего плохого в расширении Throwable, чтобы иметь возможность генерировать (и обрабатывать) пользовательские исключения. Тем не менее, вы должны помнить следующее:
Итак, предположим, у вас есть следующие классы исключений в вашей кодовой базе:
public class Pig extends Throwable { ... }
public class FlyingPig extends Pig { ... }
public class Swine extends Pig { ... }
public class CustomRuntimeException extends RuntimeException { ... }
И некоторые методы
public void foo() throws Pig { ... }
public void bar() throws FlyingPig, Swine { ... }
// suppose this next method could throw a CustomRuntimeException, but it
// doesn't need to be declared, since CustomRuntimeException is a subclass
// of RuntimeException
public void baz() { ... }
Теперь у вас может быть некоторый код, который вызывает эти методы похожи на это:
try {
foo();
} catch (Pig e) {
...
}
try {
bar();
} catch (Pig e) {
...
}
baz();
Обратите внимание, что когда мы вызываем bar()
, мы можем просто поймать Pig
, так как FlyingPig
и Swine
расширяются Pig
. Это полезно, если вы хотите сделать то же самое для обработки любого исключения. Вы могли бы, однако, обращаться с ними по-другому:
try {
bar();
} catch (FlyingPig e) {
...
} catch (Swine e) {
...
}
Если вы можете обосновать то, что отличает FlyingPig от ошибок и исключений, таким образом, что он не подходит в качестве подкласса ни того, ни другого, тогда нет ничего принципиально неправильного с его созданием.
Самая большая проблема, о которой я могу думать, - это прагматический мир, иногда есть веские причины для перехвата java.lang.Exception. Ваш новый тип throwable будет пролетать мимо блоков try-catch, которые имели все разумные ожидания подавления (или регистрации, упаковки и т.д.) всех возможных нефатальных проблем.
С другой стороны, если вы проводите обслуживание старой системы, которая un оправданно подавляет java.lang.Exception, вы можете обмануть ее. (Предполагая, что искренний призыв потратить время на то, чтобы исправить это должным образом, отклоняется).
Аннотация org.junit.Test
включает класс None
, который расширяет Throwable
и используется в качестве значения по умолчанию для ожидаемого
] параметр аннотации.
Играй! framework использует что-то подобное для обработки запросов. Обработка запроса проходит через множество уровней (маршрутизация, промежуточное ПО, контроллеры, рендеринг шаблонов), и на последнем уровне визуализированный HTML обертывается в бросок и выбрасывается, который самый верхний уровень перехватывает, разворачивает и отправляет в клиент. Таким образом, ни одному из методов во многих задействованных слоях не нужно явно возвращать объект ответа, а также им не нужно передавать объект ответа в качестве аргумента для распространения и изменения.
Я немного поверхностен в деталях. Вы можете просмотреть код Play! рамки для деталей.
Вот запись в блоге Джона Роуза, архитектора HotSpot:
http://blogs.oracle.com/jrose/entry/longjumps_considered_inexpensive
Речь идет о «злоупотреблении» исключениями для управления потоком. Немного другой вариант использования, но.. Короче говоря, это работает очень хорошо - если вы предварительно выделяете/клонируете свои исключения, чтобы предотвратить создание трассировки стека.
Я думаю, что этот метод оправдан, если он «спрятан» от клиентов. IE, ваш FlyingPig никогда не сможет покинуть вашу библиотеку (все общедоступные методы должны транзитивно гарантировать, что он не будет выброшен). Один из способов гарантировать это — сделать его проверенным исключением.
Я думаю, что единственное оправдание для расширения Throwable состоит в том, что вы хотите, чтобы люди могли передавать обратные вызовы, которые имеют предложения catch(Exception e), и вы хотите, чтобы они игнорировали ваш результат. Я почти могу купить это...