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

Горячий напиток Неизменяемый/Автоматическое значение/Ломбок 🔥 какой?

В этой статье мы собираемся сравнить некоторые особенности Immutables.org библиотека, значение Google Auto и проект Ломбок. Помеченный java, лучшими практиками, неизменяемостью.

Статья была первоначально опубликована по адресу Карлос chac.in

Смотрите также:

🎩 Неизменяемость на Java 🔥 Упрощено

Карлос Чачин ☕ 👽 – 12 апреля – 10 минут читать

В этой статье мы собираемся сравнить некоторые особенности Immutables.org библиотека, Автоматическое значение Google и Проект Ломбок :

  • Сгенерировал шаблон Builder по умолчанию?
  • Сгенерированные вспомогательные методы для, т. е. Необязательно и Список ?
  • Количество строк кода для написания?
  • Необходимые плагины IDE?
  • Являются ли объекты неизменяемыми?

Три библиотеки основаны на процессоре аннотаций для генерации/изменения кода для нас:

  • Неизменяемые классы
  • равно , Хэш-код и toString методы
  • другие коммунальные услуги

ПРИМЕЧАНИЕ: Неизменяемый и Автоматическое значение генерирует новые классы с помощью процессора, и Ломбок изменяет байт-код исходного класса.

Обзор 💡

Неизменяемый Процессоры аннотаций Java для создания простых, безопасных и согласованных объектов значений. Не повторяйтесь, попробуйте Неизменяемый, самый полный инструмент в этой области!

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

Project Lombok – это библиотека java, которая автоматически подключается к вашему редактору и инструментам сборки, улучшая вашу java. Никогда больше не пишите другой метод getter или equals, с одной аннотацией ваш класс имеет полнофункциональный конструктор, автоматизирует ваши переменные ведения журнала и многое другое.

📇 Модель

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

Optional myOptional;
String myString;
List myList;

🔩 Создание модели с автоматическим значением

package autovalue;

import com.google.auto.value.AutoValue;

import java.util.List;
import java.util.Optional;

@AutoValue
public abstract class MyModel {
    public abstract Optional myOptional();

    public abstract String myString();

    public abstract List myList();

    // Builder not generated by default
    // We have to write this boilerplate code
    @AutoValue.Builder
    public abstract static class Builder {
        public abstract Builder setMyOptional(Optional myOptional);

        public abstract Builder setMyString(String myString);

        public abstract Builder setMyList(List myList);

        public abstract MyModel build();
    }
}
  • Сгенерировал шаблон Builder по умолчанию? 🔴
  • Сгенерированные вспомогательные методы для, т. е. Необязательно и Список ? 🔴 Давайте посмотрим в следующем разделе
  • Количество строк кода для написания? 28 проверка
  • Для этого требуется плагин IDE 🔴
  • Являются ли объекты неизменяемыми? 🔴 Давайте посмотрим в следующем разделе

🔩 Создание модели с помощью Ломбока

package lombok;

import java.util.List;
import java.util.Optional;

@Value
@Builder
public class MyModel {
    Optional myOptional;

    String myString;

    List myList;
}
  • Сгенерировал шаблон Builder по умолчанию? 🔴
  • Сгенерированные вспомогательные методы для, т. е. Необязательно и Список ? 🔴 Давайте посмотрим в следующем разделе
  • Количество строк кода для написания? 14 проверка
  • Для этого требуются плагины IDE 🔴
  • Являются ли объекты неизменяемыми? 🔴 Давайте посмотрим в следующем разделе

🔩 Создание модели с неизменяемым

package immutables;

import org.immutables.value.Value;

import java.util.List;
import java.util.Optional;

@Value.Immutable
public interface MyModel {
    Optional myOptional();

    String myString();

    List myList();
}
  • Сгенерировал шаблон Builder по умолчанию? ✅
  • Сгенерированные вспомогательные методы для, т. е. Необязательно и Список ? ✅ , Давайте посмотрим в следующем разделе
  • Количество строк кода для написания? 15 проверка
  • Для этого не требуется плагин IDE ✅
  • Являются ли объекты неизменяемыми? ✅ , Давайте посмотрим в следующем разделе

🌵 Тесты

Давайте проверим какой-нибудь псевдокод:

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

list1=List.of("OneValue")
list2=List.of("OneValue")

Мы собираемся создать два идентичных объекта ценности, подобных этому:

MyModel1: (
  myOptional=Optional.of(1)
  myString="Hello"
  myList=list1 // Using list 1
)

MyModel2: (
  myOptional=Optional.of(1)
  myString="Hello"
  myList=list2 // Using list 2
)

Даже при использовании разных ссылок для списков объекты должны быть равны по значению.

model1 == model2 // TRUE

После изменения одного из списков сравнение объектов должно быть одинаковым

list1.add("AnotherValue")

model1 == model2 // TRUE

🍭 Проверка Автоматического значения

@Test
void immutability() {
    // Create 2 lists containing the same element
    var myList1 = new ArrayList();
    myList1.add("OneValue");
    var myList2 = List.of("OneValue");

    // Create model 1, assigning the list1
    var myModel1 = new AutoValue_MyModel.Builder()
            .setMyOptional(Optional.of(1)) // 😥 🔴 No helper for Optional
            .setMyString("Hello")
            .setMyList(myList1) // 😥 🔴 No helper for List
            .build();

    // Create model 2, assigning the list2
    var myModel2 = new AutoValue_MyModel.Builder() // 😥 🔴 No helper for copying
            .setMyOptional(Optional.of(1))
            .setMyString("Hello")
            .setMyList(myList2)
            .build();

    // Compare the 2 objects
    // Test passes since the fields contain the same values
    assertThat(myModel1).isEqualTo(myModel2);

    // Mutate the list used on Model 1
    myList1.add("AnotherValue");

    // Compare the 2 objects:
    // - PASSES objects are NOT equal for AutoValue 😮 🔴
    assertThat(myModel1).isNotEqualTo(myModel2);
}

🍭 Тестирование Ломбока

@Test
void immutability() {
    // Create a mutable list with 1 element
    var myList1 = new ArrayList();
    myList1.add("OneValue");
    var myList2 = List.of("OneValue");

    // Create model 1, assigning the list1
    var myModel1 = MyModel.builder()
            .myOptional(Optional.of(1)) // 😥 🔴 No helper for Optional
            .myString("Hello")
            .myList(myList1) // 😥 🔴 No helper for List
            .build();

    // Create model 2, assigning the list2
    var myModel2 = MyModel.builder() 😥 🔴 // No helper for copying
            .myOptional(Optional.of(1))
            .myString("Hello")
            .myList(myList2)
            .build();

    // Compare the 2 objects
    // Test passes since the fields contain the same values
    assertThat(myModel1).isEqualTo(myModel2);

    // Mutate the list used on Model 1
    myList1.add("AnotherValue");

    // Compare the 2 objects:
    // - PASSES objects are NOT equal for Lombok 😮 🔴
    assertThat(myModel1).isNotEqualTo(myModel2);
}

🍭 Тестирование неизменяемых

@Test
void immutability() {
   // Create a mutable list with 1 element
   var myList1 = new ArrayList();
    myList1.add("OneValue");
    var myList2 = List.of("OneValue");

   // Create model 1, assigning the list1
   var myModel1 = ImmutableMyModel.builder()
           .myOptional(1) // 🎩 ✅ Helper for Optional
           .myString("Hello")
           .myList(myList1)
           .build();

   // Create model 2, assigning the list2
   var myModel2 = ImmutableMyModel.builder()
           .from(myModel1) // 🎩 ✅ Helper for copying
           .addMyList("OneValue") // 🎩 ✅ Helper for List
           .build();

   // Compare the 2 objects
   // Test passes since the fields contain the same values
   assertThat(myModel1).isEqualTo(myModel2);

   // Mutate the list used on Model 1
   myList1.add("AnotherValue");

   // Compare the 2 objects:
   // - Test PASSES objects ARE EQUAL for Immutables 🎩 ✅
   assertThat(myModel1).isEqualTo(myModel2);
}

📈 Результаты

14 28 15 Строка кода для написания/ поддерживать
🔴 🔴 Конструктор (по умолчанию)
🔴 Необходимый плагин IDE
🔴 🔴 Неизменность
🔴 🔴 Помощник для дополнительного
🔴 🔴 Помощник для коллекций
🔴 🔴 Помощник для копирования

Код и тесты для приведенных выше примеров доступны на GitHub:

cchacin/неизменяемые – автоматическое значение -ломбок

Горячий напиток Неизменяемый/Автоматическое значение/Ломбок 🔥 какой?

Запись в блоге: https://dev.to/cchacin/immutables-autovalue-lombok-which-one-2j33

Выводы 🔆

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

  • Справедливости ради, оба Ломбок и Автоматическое значение может также обеспечить неизменность но это требует большего внимания при создании классов, и это может вызвать проблемы.

  • Одним из основных преимуществ автоматического значения является то, что он генерирует меньше кода, и это было бы удобно, если вы разрабатываете/для Android .

  • Параметры конфигурации для Автоматического значения и Ломбок довольно ограничены по сравнению с Неизменяемый но эта тема не была затронута в этой статье.

  • Для Lombok требуется плагин, если вы хотите видеть все измененные/добавленные методы в байт-код.

Оригинал: “https://dev.to/cchacin/immutables-autovalue-lombok-which-one-2j33”