1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【デザインパターン】ビルダーパターン解説(Flutter / Android 実例付き)

Last updated at Posted at 2025-08-23

1. パターンの意図

ビルダーパターン(Builder) は、複雑なオブジェクトを段階的に組み立てる仕組みを提供するデザインパターンです。

解決する問題

  • コンストラクタの引数が多すぎて可読性が落ちる(テレスコーピングコンストラクタ問題
  • オプション項目が多いオブジェクトを柔軟に生成したい
  • オブジェクトの組み立て過程を隠蔽しつつ、利用者にはシンプルな API を提供したい

ポイント

  • 分かりやすいメソッドチェーンでオブジェクトを構築
  • 必須項目と任意項目を区別できる
  • 「構築の手順」と「最終製品」を分離できる

2. UML 図


3. Flutter / Dart 実装例

3.1 Product

class User {
  final String name;
  final int age;
  final String? email;
  final String? phone;

  User._builder(UserBuilder builder)
      : name = builder.name,
        age = builder.age,
        email = builder.email,
        phone = builder.phone;

  @override
  String toString() => 'User(name: $name, age: $age, email: $email, phone: $phone)';
}

3.2 Builder

class UserBuilder {
  final String name;
  final int age;
  String? email;
  String? phone;

  UserBuilder({required this.name, required this.age});

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

  UserBuilder setPhone(String phone) {
    this.phone = phone;
    return this;
  }

  User build() => User._builder(this);
}

3.3 利用例

void main() {
  var user = UserBuilder(name: "Anna", age: 25)
      .setEmail("anna@example.com")
      .setPhone("123-456")
      .build();

  print(user); 
  // User(name: Anna, age: 25, email: anna@example.com, phone: 123-456)
}

4. Android / Kotlin 実装例

4.1 Product

class User private constructor(
    val name: String,
    val age: Int,
    val email: String?,
    val phone: String?
) {
    class Builder(val name: String, val age: Int) {
        private var email: String? = null
        private var phone: String? = null

        fun setEmail(email: String) = apply { this.email = email }
        fun setPhone(phone: String) = apply { this.phone = phone }

        fun build(): User = User(name, age, email, phone)
    }

    override fun toString(): String {
        return "User(name=$name, age=$age, email=$email, phone=$phone)"
    }
}

4.2 利用例

fun main() {
    val user = User.Builder("Anna", 25)
        .setEmail("anna@example.com")
        .setPhone("123-456")
        .build()

    println(user)
}

5. メリット / デメリット

メリット

  • 複雑なオブジェクト生成を分かりやすく整理できる
  • 必須/任意プロパティを区別可能
  • メソッドチェーンで直感的に記述できる

デメリット

  • クラスが増える(Builder クラスが必要)
  • シンプルなオブジェクトにはオーバーエンジニアリングになる

6. 実務ユースケース

Flutter

  • ネットワークリクエスト(Dio の RequestOptions
  • UI コンポーネントの段階的構築(Dialog, Form)
  • 設定ファイルや複雑なモデル構築

Android (Kotlin)

  • AlertDialog.BuilderNotificationCompat.Builder
  • Retrofit リクエストオプション
  • データクラスの段階的構築

7. 実装上の注意点

Flutter / Dart

  • 必須フィールドUserBuilder のコンストラクタで受け取り、任意フィールドは setter で追加する
  • copyWith と組み合わせると「ビルダー+イミュータブル」設計が可能

Android / Kotlin

  • Kotlin では data class + copy() が強力なので、Builder は必須ではない
  • ただし Java 互換 API や Android 標準 API(Dialog など) では依然としてよく使われる

8. どんなときに使う?

  • コンストラクタの引数が 4つ以上でオプションが多い
  • オブジェクト生成を 可読性よく表現したい
  • 段階的な組み立て手順を明示化したい

まとめ

  • ビルダーパターンは「複雑なオブジェクトを段階的に構築する」ための仕組み
  • Flutter では Dio リクエストや UI 構築に応用され、Android では AlertDialog.Builder が代表例
  • 必須項目と任意項目を分けられる点が最大の強み
  • Kotlin では copy() で代替できる場面も多いが、Java 互換性や柔軟性が求められる場合は有効
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?