Използване на @Builder Annotation на Lombok

1. Общ преглед

@Builder на Project Lombok е полезен механизъм за използване на шаблона на Builder без писане на шаблонния код. Можем да приложим тази анотация към клас или метод.

В този кратък урок ще разгледаме различните случаи на използване на @Builder .

2. Зависимости на Maven

Първо, трябва да добавим Project Lombok към нашия pom.xml :

 org.projectlombok lombok 1.18.10 

Maven Central има най-новата версия на Project 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);

Ако искаме да създадем копия или близки копия на обекти, можем да добавим свойството toBuilder = true към анотацията @Builder :

@Builder(toBuilder = true) public class Widget { //... }

Това казва на Lombok да добави метод toBuilder () към нашия клас . Когато извикаме метода 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); } }

В този случай ние крием конструктора по подразбиране като internalBuilder и създаваме свой собствен. По този начин, когато създаваме конструктора, трябва да предоставим необходимия параметър:

RequiredField.builder("NameField").description("Field Description").build();

Също така, за да сме сигурни, че нашето поле съществува, можем да добавим анотацията @NonNull .

4. Използване на @Builder за метод

Да предположим, че използваме обект, който искаме да конструираме с конструктор, но не можем да модифицираме източника или да разширим класа .

Първо, нека създадем бърз пример, използвайки анотацията @Value на Lombok:

@Value final class ImmutableClient { private int id; private String name; }

Сега имаме окончателен клас с два неизменяеми члена, гетери за тях и конструктор на всички аргументи.

Ние разгледахме как да използваме @Builder за клас , но можем да го използваме и за методи. Ще използваме тази способност, за да заобиколим неспособността да модифицираме или разширим ImmutableClient .

След това ще създадем нов клас с метод за създаване на ImmutableClients:

class ClientBuilder { @Builder(builderMethodName = "builder") public static ImmutableClient newClient(int id, String name) { return new ImmutableClient(id, name); } }

Тази анотация създава метод с име builder (), който връща Builder за създаване на ImmutableClients .

Сега нека да изградим ImmutableClient :

ImmutableClient testImmutableClient = ClientBuilder.builder() .name("foo") .id(1) .build(); assertThat(testImmutableClient.getName()) .isEqualTo("foo"); assertThat(testImmutableClient.getId()) .isEqualTo(1);

5. Заключение

В тази статия използвахме анотацията на Lombok @Builder за метод за създаване на конструктор за окончателен клас и видяхме как да направим някои от полетата на класа задължителни.

Примери за кодове, както винаги, можете да намерите в GitHub.