1. 概要

ProjectLombokの@Builderは、ボイラープレートコードを記述せずにBuilderパターンを使用するための便利なメカニズムです。 このアノテーションをClassまたはメソッドに適用できます。

このクイックチュートリアルでは、@Builderのさまざまなユースケースを見ていきます。

2. Mavenの依存関係

まず、 ProjectLombokpom.xmlに追加する必要があります。

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
</dependency>

Maven Centralには、最新バージョンのProjectLombokがあります。

3. クラスでの@Builderの使用

最初のユースケースでは、単に Class を実装しているだけであり、ビルダーを使用してクラスのインスタンスを作成したいと考えています。

最初で唯一のステップは、クラス宣言にアノテーションを追加することです。

@Getter
@Builder
public class Widget {
    private final String name;
    private final int id;
}

Lombokがすべての作業を行います。ウィジェットを作成してテストできるようになりました。

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 {
//...
}

これは、 toBuilder()メソッドをクラスに追加するようにLombokに指示します。 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);

テストコードでは、Lombokによって生成されたビルダークラスの名前が、「Builder」が追加されたクラスのようになっていることがわかります。この場合はWidgetBuilderです。次に、必要なプロパティを変更し、 build()新しいインスタンスを変更できます。

必須フィールドを指定する必要がある場合は、注釈構成を使用して補助ビルダーを作成できます。

@Builder(builderMethodName = "internalBuilder")
public class RequiredFieldAnnotation {
    @NonNull
    private String name;
    private String description;

    public static RequiredFieldAnnotationBuilder builder(String name) {
        return internalBuilder().name(name);
    }
}

この場合、デフォルトのbuilderinternalBuilderとして非表示にし、独自のものを作成しています。 したがって、ビルダーを作成するときは、必要なパラメーターを指定する必要があります。

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

また、フィールドが存在することを確認するために、@NonNullアノテーションを追加できます。

4. メソッドで@Builderを使用する

ビルダーで構築したいオブジェクトを使用しているが、ソースを変更したり、クラスを拡張したりすることはできません。

まず、 Lombokの@Valueアノテーションを使用して簡単な例を作成しましょう:

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

これで、2つの不変メンバー、それらのゲッター、およびすべての引数のコンストラクターを持つ final Classができました。

クラスで@Builderを使用する方法について説明しましたが、メソッドでも使用できます。この機能を使用して、ImmutableClientを変更または拡張できない問題を回避します。

次に、ImmutableClientsを作成するためのメソッドを使用して新しいクラスを作成します。

class ClientBuilder {

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

このアノテーションは、 builder()という名前のメソッドを作成し、はImmutableClientsを作成するためのビルダーを返します。

それでは、ImmutableClientを作成しましょう。

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

5. 結論

この短い記事では、 final Class、のビルダーを作成するメソッドにLombokの @Builder アノテーションを使用し、いくつかの作成方法を学びました。 クラスフィールドが必要です。

コードサンプルは、いつものように、GitHubにあります。