Java Необязательный в полях класса? Почему бы и нет.

По желанию был представлен в Java 8 и, согласно документации,
предполагается ограничить использование null в ответ на методы.

Optional класс не сериализуем, поэтому он не предназначен для использования в качестве полей
в Java-бинах.

Как заявил Брайан Гетц на Переполнение стека
«регулярное использование его в качестве возвращаемого значения для геттеров определенно будет чрезмерным».

Я согласен с утверждением, что их нужно использовать с осторожностью и уж точно не как панацею от всех проблем.

я случайно увидел использование Optional в таких контекстах, как показано ниже, чтобы избежать использования операторов if-else в пользу более функционального стиля программирования:

Optional.ofNullable(aField)
  .map(this::doSthWithTheField)
  .orElse(this::doSthElse)

против старого доброго императивного стиля:

if(aField==null){
  doSthWithTheField(aField);
}else{
  doSthElse(aField);
}

Это использование Optional уже перерасход или нет?

Думаю, это дело вкуса, прагматизма и согласия в команде.
На мой взгляд, это немного беспорядочно, если иногда if-else, а иногда и структура, подобная приведенной выше, используется вокруг кода курса одного проекта.

Лично мне больше нравится версия с Optional.

Как насчет сумасшедшей идеи использования опций в вашем объекте передачи домена (DTO)?

Или все не так уж и безумно?

Читайте дальше, чтобы проверить, подходит ли вам этот подход.

Представьте, что у вас есть бизнес-домен с классом User как показано ниже:

class User{
  private String name;
  private String secondName;

  public String getName(){
    return name;
  }
  public Optional<String> getSecondName(){
    return Optional.ofNullable(name)
  }

  // skipped setters for readability
}

Ваш User имеет такие атрибуты, как name который требуется (не нуль), и secondName который может быть пустым.
Имея это, вам больше нигде не нужно беспокоиться о том, что вы можете получить второе имя, которое null.
Например, вы можете использовать его так:

User user = ...
String userName = user.getName();
String displayedName = user.getSecondName()
  .map(s-> userName + ", " + s)
  .orElse(userName);

вместо:

User user = ...
String userName = user.getName();
String second = user.getSecondName();
String displayedName = null;
if(second != null){
  displayedName = userName + ", " + second;
} else {
  displayedName = userName;
}

Увидеть разницу? Более того, когда вы смотрите на геттеры доменных классов, вы уже знаете, какие поля являются необязательными, ваш код самодокументируется.

А что, если вам нужно передать такой объект домена в ответ от контроллера?

Обычно вы, вероятно, хотели бы обернуть его в объект передачи домена, например UserResponse но для простоты предположим, что вы вернетесь User в контроллере.

Как Spring узнает, как преобразовать Optional значение в JSON?
Ну.. не будет по умолчанию. Это потребует общедоступного метода получения Optional класс, который isPresent() и используйте его в JSON, например:

{"name":"Marcin","secondName":{"present":true}}

Для обеспечения правильного преобразования в библиотеке Джексона есть модуль, предназначенный для типов Java 8.
Используя Maven, нам нужно добавить эту зависимость:

<dependency>
   <groupId>com.fasterxml.jackson.datatype</groupId>
   <artifactId>jackson-datatype-jdk8</artifactId>
   <version>2.9.6</version>
</dependency>

и зарегистрируйте его в ObjectMapper как это:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());

Хорошая новость заключается в том, что если вы используете Spring Boot с spring-boot-starter-web
зависимость, в ней уже все настроено и готово к использованию 😃

Скриншот 2018-10-26 на 01.03.11.png

Здесь это демо для этого поста.

Если вам понравилась тема, вам может понравиться и другое чтение:

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *