Skip to content

Builderパターン、使ってますか?

2025-01-14

Builderパターンとは?

Builderパターンとは、複雑なオブジェクトの生成を段階的に行うための設計パターンです。

特に コンストラクタの引数が多くなったり、可読性が低下しやすいケース で有効です。

なぜ必要なのか

仮に、以下のようなコードがあったとします。

java
User user = new User("Alice", "[email protected]", 30, "Engineer", "Japan", true);

このコードを見て、どの引数が何を表しているのかが一目でわかりません。

また、Javaは引数を順番通りに渡す必要があるため、引数の順番を間違えるとバグの原因になります。

Builderパターンを使うと

java
public static void main(String[] args) {
    User user = new User.Builder()
            .setName("Alice")
            .setEmail("[email protected]")
            .setAge(30)
            .setJob("Engineer")
            .setCountry("Japan")
            .setNewsletter(true)
            .build();
}

Builderパターンを使うと、メソッドチェーンでフィールドを設定できるため、可読性が向上します。

渡す引数が多くなればなるほど、Builderパターンを使うメリットが大きくなるのがわかりますね。

Builderパターンの実装方法

Builderクラスは、Userクラスのインスタンスを生成するためのメソッドを持っており、
Userクラスのフィールドを設定するためのメソッドをチェーンで呼び出すことができます。

java
public class User {
    private final String name;
    private final String email;
    private final int age;
    private final String job;
    private final String country;
    private final boolean newsletter;

    private User(Builder builder) {
        this.name = builder.name;
        this.email = builder.email;
        this.age = builder.age;
        this.job = builder.job;
        this.country = builder.country;
        this.newsletter = builder.newsletter;
    }

    public static class Builder {
        private String name;
        private String email;
        private int age;
        private String job;
        private String country;
        private boolean newsletter;

        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        public Builder setEmail(String email) {
            this.email = email;
            return this;
        }

        public Builder setAge(int age) {
            this.age = age;
            return this;
        }

        public Builder setJob(String job) {
            this.job = job;
            return this;
        }

        public Builder setCountry(String country) {
            this.country = country;
            return this;
        }

        public Builder setNewsletter(boolean newsletter) {
            this.newsletter = newsletter;
            return this;
        }

        public User build() {
            return new User(this);
        }
    }
}

TIP

Lombokの @Builder アノテーションを使うことで、簡単に実装できます。

java

@Builder
public class User {
    private String name;
    private String email;
    private int age;
    private String job;
    private String country;
    private boolean newsletter;

    public static void main(String[] args) {
        User user = User.builder()
                .name("Alice")
                .email("[email protected]")
                .age(30)
                .job("Engineer")
                .country("Japan")
                .newsletter(true)
                .build();
    }
}

まとめ

ビルダーを使うべきケース

  • 引数が多く、順番が分かりづらい
  • オプションパラメータが多い
  • イミュータブルなオブジェクトを作りたい
  • 柔軟で分かりやすいオブジェクトの初期化が必要

使わなくてもいいケース

  • フィールドが少なく、単純なオブジェクト
  • 何度もインスタンスを作るようなパフォーマンス重視の処理(ビルダーを作るコストが無駄)

© 2024 KyotoKankoTechBlog. All rights reserved.