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

Использование системы типов Java для представления особых состояний

Сделайте специальные состояния явными. С тегом java, начинающие.

Как известно каждому разработчику Java, переменные с непримитивными типами инициализируются в null . Это Java (и не только Java) способ сказать, что “значение отсутствует” или “переменной еще не присвоено значение”.

Часто возникают ситуации, когда мы можем возвращать значение, но иногда нам нужно уведомить вызывающего абонента об ошибке. Идиоматический способ Java сделать это – создать исключение.

Что общего у описанных выше ситуаций? Они охватывают разные случаи и используют разные способы их представления/обработки.

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

Переменные Особые Состояния

Что такое переменное особое состояние? Особое состояние переменной – это состояние, когда значение переменной по какой-либо причине (пока) недоступно.

Существует три особых состояния переменных:

  • Значение переменной отсутствует
  • Операция может возвращать значение или сообщать об ошибке, поэтому значение может присутствовать или отсутствовать
  • Переменная содержит результат асинхронной операции, которая все еще выполняется, поэтому значение еще недоступно.

Давайте посмотрим, как эти дела решались традиционно.

Отсутствующее Значение

Традиционный способ представления отсутствующих в Java заключается в присвоении переменной null . Этот подход имеет ряд недостатков и является источником огромного количества ошибок. Забавно, но даже сама Java не угрожает таким переменным, как реальные, с реальным типом – instanceof проверка на наличие таких переменных возвращает false .

Возвращаемое значение или Сообщение об ошибке

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

Но это только часть проблемы. Как вы уже знаете, существует два типа исключений – проверенные и непроверенные.

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

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

ещё нет Доступное Значение

Начиная с версии 8 в Java встроена поддержка для обработки этого случая – CompletableFuture . Построенный на концепциях, вдохновленных FP, он использует следующий подход для обработки еще не доступного значения: вместо того, чтобы позволить пользовательскому коду получить доступ к значению, CompletableFuture имеет ряд методов, которые принимают функции (лямбды) в качестве параметра. Вызов этих функций откладывается до тех пор, пока не будет доступно значение.

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

Поиск Последовательного Подхода

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

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

Каждое особое состояние соответствует определенной монаде:

  • Опция/Необязательно/Возможно, монада обрабатывает случай пропущенного значения
  • Монада результата обрабатывает случай значения/ошибки
  • Монада обещания обрабатывает случай, когда значение еще не доступно

Монады используют систему типов Java для представления особых состояний, и это обеспечивает множество сразу ощутимых преимуществ:

  • Все специальные состояния сразу видны в коде. Нет необходимости тратить время на навигацию и чтение кода, чтобы убедиться, что он/не возвращает null или создает исключение.
  • Значительно уменьшен стандартный код и улучшена читаемость кода. Все повторяющиеся проверки, такие как if (переменная) , исчезают, и разработчик может писать код так, как будто существует только “сценарий счастливого дня”, оставляя окончательное решение за вызывающим.
  • Компилятор – ваш лучший друг, который гарантирует, что каждый отдельный особый случай будет рассмотрен и правильно обработан.

В долгосрочной перспективе есть более тонкие, но не менее ценные преимущества:

  • Вместе с объявлением Java 11 var и выводом типов код на основе монад содержит почти все избыточные объявления типов.
  • Существует естественная тенденция разбивать код на небольшие, обобщенные, многократно используемые, легко читаемые и понятные, ориентированные на отдельные функции задачи.
  • Сокращенный шаблон делает бизнес-логику гораздо более заметной в коде, ее легче читать и понимать. Общая кодовая база выглядит и ощущается на более высоком уровне.
  • Значительно уменьшено количество ошибок, особенно низкоуровневых, таких как отсутствие нулевой проверки или необработанное исключение.
  • Код проще тестировать, обычно требуется меньше насмешек.
  • Обработка особых состояний происходит прозрачно, и для обычного внутреннего кода можно легко перемещаться по всей цепочке вызовов туда и обратно. Нет скрытых путей выполнения, таких как выделенные обработчики исключений, которые не имеют видимой связи с кодом, но могут повлиять на результирующий ответ.
  • Значительно снижены умственные затраты, что позволяет глубже сосредоточиться на бизнес-логике высокого уровня и значительно повышает производительность.

Оригинал: “https://dev.to/siy/leveraging-java-type-system-to-represent-special-states-688”