Автор оригинала: Eric Goebelbecker.
1. Обзор
Проект Ломбока @Builder является полезным механизмом для использования шаблона Builder без написания шаблонного кода. Мы можем применить эту аннотацию к классу или методу.
В этом кратком руководстве мы рассмотрим различные варианты использования @Builder .
2. Зависимости Maven
Во-первых, нам нужно добавить Project Lombok в ваш pom.xml :
org.projectlombok lombok 1.18.10
У Maven Central есть последняя версия проекта Lombok здесь.
3. Использование @Builder в классе
В первом случае мы просто реализуем Класс , и мы хотим использовать конструктор для создания экземпляров нашего класса.
Первым и единственным шагом является добавление аннотации к объявлению класса:
@Getter @Builder public class Widget { private final String name; private final int id; }
Ломбок делает всю работу за нас. Теперь мы можем создать Виджет и протестировать его:
Widget testWidget = Widget.builder() .name("foo") .id(1) .build(); assertThat(testWidget.getName()) .isEqualTo("foo"); assertThat(testWidget.getId()) .isEqualTo(1);
Если мы хотим создать копии или близкие копии объектов, мы можем добавить свойство в Builder в @Builder аннотацию :
@Builder(toBuilder = true) public class Widget { //... }
Это говорит Ломбоку добавить метод to Builder() в наш Класс . Когда мы вызываем метод toBuilder () , он возвращает конструктор, инициализированный свойствами экземпляра, на котором он вызывается:
Widget testWidget = Widget.builder() .name("foo") .id(1) .build(); Widget.WidgetBuilder widgetBuilder = testWidget.toBuilder(); Widget newWidget = widgetBuilder.id(2).build(); assertThat(newWidget.getName()) .isEqualTo("foo"); assertThat(newWidget.getId()) .isEqualTo(2);
В тестовом коде мы видим, что класс builder, созданный Lombok, назван так же, как и наш класс, с добавлением “Builder” к нему — WidgetBuilder в данном случае. Затем мы можем изменить свойства, которые мы хотим, и построить() новый экземпляр.
Если нам нужно указать необходимые поля, мы можем использовать конфигурацию аннотаций для создания вспомогательного конструктора:
@Builder(builderMethodName = "internalBuilder") public class RequiredFieldAnnotation { @NonNull private String name; private String description; public static RequiredFieldAnnotationBuilder builder(String name) { return internalBuilder().name(name); } }
В этом случае мы скрываем builder по умолчанию как внутренний конструктор и создаем свой собственный. Таким образом, при создании конструктора мы должны указать необходимый параметр:
RequiredField.builder("NameField").description("Field Description").build();
Кроме того, чтобы убедиться, что наше поле существует, мы можем добавить аннотацию @NonNull .
4. Использование @Builder в методе
Предположим, мы используем объект, который хотим построить с помощью конструктора, но мы не можем изменить исходный код или расширить класс .
Во-первых, давайте создадим быстрый пример, используя аннотацию @Value Ломбока:
@Value final class ImmutableClient { private int id; private String name; }
Теперь у нас есть final Класс с двумя неизменяемыми членами, геттерами для них и конструктором всех аргументов.
Мы рассмотрели , как использовать @Builder в классе , но мы можем использовать его и в методах. Мы будем использовать эту возможность, чтобы обойти невозможность изменения или расширения Неизменяемого клиента .
Далее мы создадим новый класс с методом создания неизменяемых клиентов:
class ClientBuilder { @Builder(builderMethodName = "builder") public static ImmutableClient newClient(int id, String name) { return new ImmutableClient(id, name); } }
Эта аннотация создает метод с именем builder () , который возвращает Builder для создания Неизменяемых клиентов .
Теперь давайте создадим Неизменяемый клиент :
ImmutableClient testImmutableClient = ClientBuilder.builder() .name("foo") .id(1) .build(); assertThat(testImmutableClient.getName()) .isEqualTo("foo"); assertThat(testImmutableClient.getId()) .isEqualTo(1);
5. Заключение
В этой статье мы использовали Lombok @Builder аннотацию к методу для создания конструктора для final | класса, и мы увидели, как сделать некоторые из полей Class необходимыми.
Примеры кода, как всегда, можно найти на GitHub .