Builder в одну строку

BuilderPatterns-Vb.netШаблон проектирования , цитирую, «отделяет конструирование сложного объекта от его представления, так что в результате одного и того же процесса конструирования могут получаться разные представления.» На практике это означает, что пользоватся обычно удобно, а вот реализовывать его — адов геморрой.

@Builder

В project реализация Builder для какого-либо класса делается одной строкой:

@Builder делает кучу вещей: создаёт статический метод builder(); генерирует внутренний класс, реализующий Builder; генерирует код этого класса, устанавливающий фактические значения; генерирует для него метод toString(); и, наконец, генерирует метод build(), создающий ваш класс.  Кроме того, поведение аннотации @Builder можно настраивать:

  • Параметр builderClassName задаёт имя внутреннего класса (по умолчанию «конструируемый тип+Builder»).
  • Параметр buildMethodName задаёт имя метода, создающего ваш класс (по умолчанию build())
  • Параметр builderMethodName задаёт имя статического метода, возвращающего Builder (по умолчанию builder())
  • Параметр toBuilder=true генерирует метод toBuilder(). Метод toBuilder() позволяет построить Builder из уже существующего класса, который будет инициализирован данными класса. По умолчанию такой метод не создаётся.

Использовать автоматически сгеренированный Builder проще простого:

@Singular

Аннотация @Singular упрощает строительство коллекций. Если поле аннотировано @Singular, для него будет сформировано два метода добавления в коллекцию: один метод принимает единственный элемент будущей коллекции и добавляет его к ней, второй принимает коллекцию и добавляет её к будущей коллекции. Методов для замены будущей коллекции не будет сгенерировано.

@Singular работает только с некоторыми типами коллекций, как то:

  • Iterable, Collection, List
  • Set, SortedSet, NavigableSet
  • Map, SortedMap, NavigableMap
  • ImmutableCollection, ImmutableList
  • ImmutableSet, ImmutableSortedSet
  • ImmutableMap, ImmutableBiMap, ImmutableSortedMap

Кроме того, аннотация @Singular анализирует имя переменной и пытается его перевести из формы множественного числа, в форму единственного числа по правилам английского языка. Например, если коллекция называется adresses, то будет сгенерировано два метода: address для одного аргумента и addresses для коллекции. В случае, если lombok не сможет перевести имя переменной из множественного числа в единственное, необходимо будет задать имя метода для одного аргумента явно в параметре аннотации.

Как видно из примера, @Builder не позволяет создавать объекты с незаполненными @NonNull полями.

В этот же тесте я использова другую функциональность lombok: ключевое слово val. val как бы говорит компилятору: «Эй, ты там ведь сам всё равно знаешь, какой-там тип у данных, так не выноси мне мозг и сделай переменную именно того типа, который нужен». Другими словами, val позволяет определить локальную переменную не указывая её типа, в случае, если она сразу будет проинициализирована. Причём переменная будет объявлена  final. val нельзя использовать для определения полей класса, параметров функций итд.

Код примера доступен на github.