🙄
デザインパターン ~FactoryMethodパターン~
FactoryMethodとは?
Template Methodパターンをインスタン生成を行う際に適用したデザインパターンのこと。
インスタンスの作り方をスーパークラス側で定めます(具体的なクラス名までは定めません)。
そして、具体的な肉付けはサブクラスで行います。
コードを書いてみよう
今回は、身分証明書カード(IDカード)を作る以下のプログラムを書いていきます。
パッケージ | 名前 | どんなクラスか |
---|---|---|
framework | Product | 抽象メソッドuseのみ定義されている抽象クラス |
framework | Factory | メソッドcreateを実装している抽象クラス |
idcard | IDcard | メソッドuseを実装しているクラス |
idcard | IDcardFactory | メソッドcreateProduct, registerProductを実装しているクラス |
無名 | Main | 動作テスト用のクラス |
まずは、抽象クラス側として「製品」を表現するProductクラスを作成します。
ここで定めているのは、「何はともあれ、useできる(使用できる)もの」としています。
Product.java
package framework;
public abstract class Product {
public abstract void use();
}
次に、抽象クラス側としてProductのインスタンスを生成し、製本の作成(createProduct)、製品の登録(registerProduct)を行うFactoryクラスを作成します
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クラスを作成します。
このクラスは、抽象クラスProductのサブクラスとして定義します。
package idcard;
import framework.*;
public class IDCard extends Product {
private String owner;
IDCard(String owner) {
System.out.println(owner + "のカードを作ります。");
this.owner = owner;
}
public void use () {
System.out.println(owner + "のカードを使います。");
}
public String getOwner() {
return owner;
}
}
次に、具体クラス側として、IDCardFactoryクラスを作成します。このクラスは、抽象クラスFactoryのサブクラスとして定義します。
package idcard;
import framework.*;
import java.util.*;
public class IDCardFactory extends Factory {
private List owners = new ArrayList();
protected Product createProduct(String owner) {
return new IDCard(owner);
}
protected void registerProduct(Product product) {
owners.add(((IDCard)product)).getOwner());
}
public List getOwners() {
return owners;
}
}
そして最後に動作確認用のMainクラスを作成します。
package idcard;
import framework.*;
public class Main {
public static void main(String[] args) {
Factory factory = new IDCardFactory();
Product card1 = factory.create("Tom");
Product card2 = factory.create("Andrew");
Product card3 = factory.create("Ketty");
card1.use();
card2.use();
card3.use();
}
}
クラス図で見てみよう
このデザインパターンにはどんなメリットがあるのか?
複数人で開発するときの意思疎通がしやすくなる
frameworkパッケージに定義されているスーパークラス側で、インスタンス生成の作り方について骨組みを決められるので、複数人で開発するときの意思疎通がしやすくなります。
継承先のパッケージに依存しない
frameworkパッケージに定義されているスーパークラス側では、それを継承して具体的に何のクラスが作られるかは知らないので、今回で言えばidcardパッケージに依存しない状態になります。
そうすることで、idcard以外のクラスを作成したい場合でも、パッケージ側には修正が不要になります。
Discussion