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();
}
}
まとめ
ビルダーを使うべきケース
- 引数が多く、順番が分かりづらい
- オプションパラメータが多い
- イミュータブルなオブジェクトを作りたい
- 柔軟で分かりやすいオブジェクトの初期化が必要
使わなくてもいいケース
- フィールドが少なく、単純なオブジェクト
- 何度もインスタンスを作るようなパフォーマンス重視の処理(ビルダーを作るコストが無駄)