0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【GoFデザインパターン】Factory Method(ファクトリーメソッド)パターンをJavaで理解する

0
Last updated at Posted at 2026-09-08

はじめに

本記事は、GoFデザインパターン解説シリーズの1つです。

今回は、生成に関するパターンの中のFactory Method(ファクトリーメソッド)パターンを、Javaのサンプルコードとともに解説します。

解決したい課題

コードの中でnew SomeClass()のように具体的なクラス名を直接書いてしまうと、そのクラスに強く依存してしまい、「別の種類のクラスに差し替えたい」となったときに、呼び出し元のコードをあちこち修正する必要が出てきます。

例えば「通知を送る」機能で、最初はメール通知だけだったものが、後からSMS通知・Push通知にも対応したくなったとします。

呼び出し元のコードで直接new EmailNotifier()と書いていると、通知の種類が増えるたびに呼び出し元のコードにも手を入れなければなりません。

Factory Methodパターンは、「何のクラスをインスタンス化するか」という決定を、専用の生成メソッド(ファクトリーメソッド)に切り出すことで、この問題を解決します。

image.png

クラス構成

  • Product(製品): 生成されるオブジェクトの共通インターフェース
  • ConcreteProduct(具体的な製品): Productを実装する、具体的なクラス群
  • Creator(生成者): ファクトリーメソッドを持つ抽象クラス(またはインターフェース)
  • ConcreteCreator(具体的な生成者): ファクトリーメソッドを実装し、特定のConcreteProductを生成するクラス

image.png

Javaでの実装例

通知(Notifier)を例に実装してみます。

Product:通知の共通インターフェース

public interface Notifier {
    void send(String message);
}

ConcreteProduct:具体的な通知クラス群

public class EmailNotifier implements Notifier {
    @Override
    public void send(String message) {
        System.out.println("[メール送信] " + message);
    }
}

public class SmsNotifier implements Notifier {
    @Override
    public void send(String message) {
        System.out.println("[SMS送信] " + message);
    }
}

public class PushNotifier implements Notifier {
    @Override
    public void send(String message) {
        System.out.println("[プッシュ通知送信] " + message);
    }
}

Creator:ファクトリーメソッドを持つ抽象クラス

public abstract class NotificationService {

    // これがファクトリーメソッド。生成方法の決定をサブクラスに委ねる
    protected abstract Notifier createNotifier();

    // ファクトリーメソッドを使う、共通のビジネスロジック
    public void notify(String message) {
        Notifier notifier = createNotifier();
        notifier.send(message);
    }
}

ConcreteCreator:どの通知手段を使うかを決める具体的なクラス

public class EmailNotificationService extends NotificationService {
    @Override
    protected Notifier createNotifier() {
        return new EmailNotifier();
    }
}

public class SmsNotificationService extends NotificationService {
    @Override
    protected Notifier createNotifier() {
        return new SmsNotifier();
    }
}

public class PushNotificationService extends NotificationService {
    @Override
    protected Notifier createNotifier() {
        return new PushNotifier();
    }
}

利用側のコード

public class Main {
    public static void main(String[] args) {
        NotificationService service1 = new EmailNotificationService();
        service1.notify("会員登録が完了しました");

        NotificationService service2 = new SmsNotificationService();
        service2.notify("認証コードは1234です");

        NotificationService service3 = new PushNotificationService();
        service3.notify("新着メッセージがあります");
    }
}

実行結果:

[メール送信] 会員登録が完了しました
[SMS送信] 認証コードは1234です
[プッシュ通知送信] 新着メッセージがあります

ポイント:共通ロジックと生成ロジックの分離

注目してほしいのは、NotificationServiceのnotify()メソッド(共通のビジネスロジック)は、どのNotifierが使われるか一切知らないという点です。

「どのクラスを生成するか」という決定だけが、サブクラス(EmailNotificationService等)に委ねられています。

新しい通知手段(例えばLINE通知)を追加したくなった場合も、NotificationService本体は一切変更せず、LineNotifierとLineNotificationServiceを新しく追加するだけで対応できます。

これは、後述する「開放閉鎖の原則(拡張には開いていて、修正には閉じている)」というオブジェクト指向設計の基本原則を体現した構造です。

image.png

Abstract Factoryパターンとの違い

Factory Methodとよく混同されるのが、次回解説するAbstract Factoryパターンです。

ざっくりとした違いは以下の通りです。

観点 Factory Method Abstract Factory
生成するもの 1種類の製品を生成するメソッド1つ 関連する複数種類の製品群を生成する、複数のメソッドを持つオブジェクト
実現方法 主に継承(サブクラスでメソッドをオーバーライド) 主にコンポジション(ファクトリーオブジェクトを注入して使う)

詳しくは、次回のAbstract Factoryパターンの記事で改めて比較します。

使用場面

  • フレームワークが処理の骨格を提供し、具体的な生成処理だけを利用者側にカスタマイズさせたい場合
  • 生成するクラスの種類が、設定や実行時の条件によって変わる場合(例: 環境ごとに異なるDBドライバーを生成する)
  • 将来的に生成するクラスの種類が増えることが予想され、呼び出し元のコードを変更せずに対応したい場合

まとめ

項目 内容
解決する課題 具体的なクラス名への直接依存を避け、生成するクラスを柔軟に切り替えたい
実現方法 インスタンス生成処理を専用メソッド(ファクトリーメソッド)に切り出し、サブクラスに委ねる
メリット 新しい種類を追加する際、既存のコードを変更せずに拡張できる
Abstract Factoryとの違い Factory Methodは1種類の製品、Abstract Factoryは関連する製品群をまとめて生成する

おすすめ書籍

GoFの23パターンをより深く学びたい方には、以下の書籍がおすすめです。
Java言語のサンプルコードとUMLを使い、初心者にもわかりやすく解説されています。

Java言語で学ぶデザインパターン入門 第3版 [ 結城 浩 ]

※本リンクはアフィリエイトリンクを含みます。

参考

0
2
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?