Рубрики
Без рубрики

Непроверенное или проверенное исключение (с очками FP)

Привет всем, для моего первого поста / статьи / чего бы то ни было здесь я решил поговорить о старом споре в… Помеченный как java, ооп, функциональный, исключения.

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

Для тех из вас, кто никогда не слышал об этом, вот краткое резюме:

  • Проверенные исключения : при вызове метода, который выдает проверенное исключение, компилятор заставит вас либо обработать его с помощью блока try-catch, либо добавить его в сигнатуру вашего метода
  • Непроверенное исключение : они расширяют класс RuntimeException и, если не обрабатываются, просто всплывают в вашем стеке вызовов.

Спор об их использовании был спорным, с проверенными исключениями, которые обычно рассматриваются как паршивая овца.

Аргументы против проверенного исключения, которые вы могли бы услышать, следующие:

Проверенные исключения можно игнорировать, проглатывая их, так в чем же смысл их наличия?

    try {
        // do stuff
    } catch (AnnoyingCheckedException e) {
        // do nothing
    }

Проверенные исключения легко игнорировать, повторно создавая их как экземпляры RuntimeException, так в чем же смысл их наличия?

    try {
        // do stuff
    } catch (AnnoyingcheckedException e) {
        throw new RuntimeException(e);
    }

Проверенные исключения приводят к нескольким объявлениям предложений throws.

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

Насколько я могу судить, в мире Java была установлена следующая передовая практика:

  • используйте проверенное исключение для общедоступного API
  • использовать Исключения во время выполнения для ваших внутренних модулей.

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

Точка зрения, которую я хочу здесь подчеркнуть, заключается в том, что:

Исключения во время выполнения являются злыми

Если вы чувствуете себя оскорбленным этим аргументом, вы можете прекратить чтение и выйти на прогулку, говорят, это действительно полезно для вашего здоровья!

Почему они злые ?

Ну, потому что всякий раз, когда вы вызываете RuntimeException из одного метода, вы говорите ложь .

Какая ложь?

Допустим, у вас есть такой метод, как:

    public Money from(BigDecimal amount, String currency) {
        if (amount.signum() < 0) {
            throw new ValidationException("whatever");
        }
        return new Money(amount, currency);
    }

Этот метод – ложь! Он сообщает своему пользователю, что вернет экземпляр Money с учетом BigDecimal и/| String , но это не так или, по крайней мере, не всегда.

Вы можете сказать: я всегда могу задокументировать это поведение с помощью теста, но все равно это не так.

Другим примером может быть:

    interface Repository {
        T save(T elem);
    }

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

Еще пара соображений:

  • учитывая их способность всплывать в стеке вызовов, Исключения во время выполнения – это не что иное, как прославленные GOTO
  • методы, которые бросают Исключения во время выполнения сложнее рассуждать, потому что вы должны хранить эту информацию в глубине своего сознания
  • слишком легко не признать Исключение RuntimeException был брошен

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

  1. значение его возвращаемого типа
  2. или значение типа проверяемого исключения он бросает

К настоящему времени, я думаю, вам, возможно, интересно, где я оставил очки FP, о которых упоминал в названии: вот они.

В мире FP (отказ от ответственности: я только в начале своего путешествия в этом мире) существует тип, предназначенный для точного выражения выбора между двумя типами: Либо A> где: A>

  • А – правильный тип (понял намек?), т.е. тип, который вы бы в идеале вернули
  • E – тип возможной ошибки это может произойти

Помимо того, что это именно то, что вы, возможно, искали, чтобы явно указать, что возвращает ваш метод, любой из них также является типом данных monadic . Не вдаваясь в кроличью нору разговоров о монадах, предположим, что монадический тип данных предоставляет 2 функции, которые упрощают работу со значением right , как только вы получаете либо в свои руки.

Эти 2 метода являются:

  1. карта которая принимает функцию f: A -> B и превратит ваш Либо A> в/| Либо B> A> в/| Либо B> B>
  2. плоская карта , которая принимает функцию f: A -> Либо B> и все равно превратит ваш B> и все равно превратит ваш Либо A>

Возможно, вы знакомы с этими 2 новыми функциями, потому что новый Stream API (начиная с Java 8) или необязательный (снова начиная с Java 8) поддерживает эти 2 функции.

И вы можете оценить, как они продвигают более декларативный способ программирования.

Либо вместо этого отсутствует в Java JDK, но вы можете найти его в (не исчерпывающий список):

  • VAR, функциональная библиотека расширений для Java ( https://www.vavr.io/ )
  • Arrow, функциональная сопутствующая библиотека для Kotlin, но вы можете использовать ее также в своем Java-коде, если хотите ( https://arrow-kt.io/ )
  • сам язык Scala ( https://www.scala-lang.org/ ).

Подход FP к функциям как к отображению между входами и выходами (и не более того) привел меня к выводу, что вы всегда должны

Возвращайте значение из вашей функции или не возвращайте его (возможно, параллель здесь не работает). Нет никакой попытки!

Или, выражаясь не в сегодняшних терминах,

Функция должна быть полной и всегда возвращать значение!

Ну, вот и все, ребята.

Надеюсь, вам это понравилось!

Оригинал: “https://dev.to/eureka84/unchecked-vs-checked-exception-with-fp-glasses-2528”