3
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?

Factory Methodパターン

0. はじめに

この記事では、Factory Methodパターンについて、以下の3点に分けて説明します。

  • 定義と利点
    Factory Methodパターンの概要とその利点について説明します。
  • 主要なコンポーネント
    パターンの主要な構成要素について詳しく解説します。
  • 実装例
    実際にJavaでFactory Methodパターンを使ったコード例を紹介し、どのように実装するのかを説明します。

1. 定義と利点

Factory Methodパターンは、オブジェクトの生成をサブクラスに任せるデザインパターンです。スーパークラスでオブジェクト生成のための「メソッドの枠組み」を定義し、具体的なオブジェクトの生成方法をサブクラスに実装させます。これにより、クライアントコードは具象クラスに依存せず、生成される製品の種類を変更することができます。

このパターンを使用すると、以下のような利点があります。

  • コードの再利用性: オブジェクト生成のロジックを共通化でき、再利用性が向上します
  • 拡張性: 新たな製品クラスを追加する際に、クライアントコードの変更が不要になるため、拡張が容易です
  • 柔軟性: 生成するオブジェクトを動的に決定できるため、柔軟な設計が可能です
  • 依存性の低減: クライアントコードは具象クラスを直接知ることなく、インターフェースや抽象クラスに依存するため、依存性が低減します

例えば、異なる種類のドキュメント(PDF、Wordなど)を生成する場合、Factory Methodパターンを使うと、ドキュメントの生成方法をサブクラスに任せ、共通の生成ロジックをスーパークラスに持たせることができます。

Factory Methodパターンは、生成されるオブジェクトの種類が決まっていない、または変更される可能性がある場合に有効です。

2. 主要なコンポーネント

Factory Methodパターンは、次の主要なコンポーネントで構成されています。

  • Product(製品)
    • 生成される製品の共通インタフェースを定義します
  • Creator(作成者)
    • Factory Methodを定義する抽象クラスを実装します
  • ConcreteProduct(具体的製品)
    • 実際に生成される製品クラスで、Productインターフェースを実装します
  • ConcreteCreator(具体的作成者)
    • Factory Methodを具体的に実装するクラスです

3. 実装例

実装例ではクラス図とコードの2点に分けて記載します。

クラス図

Factory Methodパターンのクラス図を示します。

コード

以下はFactory Methodパターンを実際に実行するためのコードです。

// Product.java
// 製品の共通インタフェースを定める
package framework;

public abstract class Product {
  public abstract void use();
}


// Factory.java
// Factory Methodを定義する抽象クラス
package framework;

public abstract class Factory {
  // 継承されないので抽象クラスにコンストラクタは不要
  public final Product create(String owner) {
    Product p = createProduct(owner);
    registerProduct(p);
    return p;
  }
  protected abstract Product createProduct(String owner);
  protected abstract void registerProduct(Product product);
}


// IDCard.java
// Productインターフェースを実装する
package idcard;
import framework.*;

public class IDCard extends Product {
  private String owner;
  private int serial;
  // コンストラクタがprivateなのでIDCardの生成にはこのpackageを経由しなければならない
  IDCard(String owner, int serial) {
    System.out.println(owner + "(" + serial + ")" + "のカードを作ります。");
    this.owner = owner;
    this.serial = serial;
  }
  public void use() {
    System.out.println(owner + "(" + serial + ")" + "のカードを使います。");
  }
  public String getOwner() {
    return owner;
  }
  public int getSerial() {
    return serial;
  }
}


// IDCardFactory.java
// createProduct, registerProductの中身を実装する
package idcard;
import framework.*;
import java.util.*;

public class IDCardFactory extends Factory {
  private HashMap<Integer, String> database = new HashMap<>();
  private int serial = 100;
  protected Product createProduct(String owner) {
    return new IDCard(owner, serial++);
  }
  protected void registerProduct(Product product) {
    IDCard card = (IDCard)product;
    database.put(new Integer(card.getSerial()), card.getOwner());
  }
  public HashMap<Integer, String> getDatabase() {
    return database;
  }
}


// FactoryTest.java
// 実行処理
import framework.*
import idcard.*;

public class FactoryTest {
  public static void main(String[] args) {
    Factory factory = new IDCardFactory();
    Product card1 = factory.create("田中克弥");
    Product card2 = factory.create("たなかかつや");
    Product card3 = factory.create("TANAKA KATSUYA");
    card1.use();
    card2.use();
    card3.use();
  }
}

参考文献

この記事は以下の情報を参考にして執筆しました。
増補改訂版 Java言語で学ぶデザインパターン入門

3
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
3
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?