Design Patterns : Facrory Method 2018/9
• 一対のインスタンス生成抽象クラス(Factory)とインスタンス定義抽象クラス(Product)を用意し、これらを継承する具象クラスを実装していくパターン。
• 実行クラスからはFactoryクラスを介してProductクラスのインスタンスを生成する 。
• 実行クラスを変更せずともFactoryクラスを変更すれば、生成されるProductクラスインスタンスを変更できる 。
UML
Productクラス(abstract)
Product具象クラス1
Product具象クラス2
Product具象クラス3
Factoryクラス(abstract)
Factory具象クラス1
Factory具象クラス2
Factory具象クラス3
Makerクラス
• 一対のインスタンス生成抽象クラス(Factory)とインスタンス定義抽象クラス(Product)を用意し、これらを継承する具象クラスを実装していくパターン。
• 実行クラスからはFactoryクラスを介してProductクラスのインスタンスを生成する 。
• 実行クラスを変更せずともFactoryクラスを変更すれば、生成されるProductクラスインスタンスを変更できる 。
UML
Productクラス(abstract)
// クラス定義の抽象クラス
public abstract class MilitaryPlane {
public abstract int speed();
public abstract int attack();
public abstract int defence();
public abstract int agile();
public abstract int bomb();
public abstract int torpedo();
public abstract String identify();
}
Product具象クラス1
// 零戦クラス
// 単体で性能を変更できる。
public class Zerosen extends MilitaryPlane {
public int speed() { return 500; };
public int attack() { return 100; };
public int defence() { return 0; };
public int agile() { return 90; };
public int bomb() { return 60; }
public int torpedo() { return 0; }
public String identify() {
return "Zerosen";
}
}
Product具象クラス2
// 天山艦攻クラス
// 単体で性能を変更できる。
public class Tenzan extends MilitaryPlane {
public int speed() { return 480; };
public int attack() { return 20; };
public int defence() { return 40; };
public int agile() { return 40; };
public int bomb() { return 800; }
public int torpedo() { return 1; }
public String identify() {
return "Tenzan";
}
}
Product具象クラス3
// 彩雲クラス
// 単体で性能を変更できる。
public class Saiun extends MilitaryPlane {
public int speed() { return 600; };
public int attack() { return 5; };
public int defence() { return 5; };
public int agile() { return 100; };
public int bomb() { return 0; }
public int torpedo() { return 0; }
public String identify() {
return "Suiun";
}
}
Factoryクラス(abstract)
// インスタンス生成クラス
public abstract class Factory {
// インスタンスの生成
public final MilitaryPlane make() {
MilitaryPlane plane = makePlane();
return plane;
}
// クラスの実装はサブクラスで行う。
protected abstract MilitaryPlane makePlane();
}
Factory具象クラス1
// 戦闘機工場
public class AttackerFactory extends Factory {
// 戦闘機作成
public MilitaryPlane makePlane() {
// 自クラス内で他のクラスと交換できる。
return new Zerosen();
}
}
Factory具象クラス2
// 爆撃機工場
public class BomberFactory extends Factory {
// 爆撃機作成
public MilitaryPlane makePlane() {
// 自クラス内で他のクラスと交換できる。
return new Tenzan();
}
}
Factory具象クラス3
// 偵察機工場
public class SurveillanceFactory extends Factory {
// 偵察機作成
public MilitaryPlane makePlane() {
// 自クラス内で他のクラスと交換できる。
return new Saiun();
}
}
Makerクラス
// 制作指示クラス
public class Maker {
// ファクトリーインスタンス
Factory attackerFactory = new AttackerFactory();
Factory bomberFactory = new BomberFactory();
Factory surveillanceFactory = new SurveillanceFactory();
public static enum Demands {
Attacker, Bomber, Surveillance
};
// 制作指示
public MilitaryPlane make(Demands demand) {
// 制作する航空機タイプを指示する。
switch(demand) {
case Attacker:
// 攻撃機の制作指示。中身は工場に任せる。
return attackerFactory.makePlane();
case Bomber:
// 爆撃機の制作指示。中身は工場に任せる。
return bomberFactory.makePlane();
case Surveillance:
// 偵察機の制作指示。中身は工場に任せる。
return surveillanceFactory.makePlane();
}
// 指示がなければ作れない。
return null;
}
// メイン
public static void main(String... args) {
Maker maker = new Maker();
// 出来上がるまでものはわからない
MilitaryPlane plane1 = maker.make(Demands.Attacker);
System.out.println(plane1.identify());
MilitaryPlane plane2 = maker.make(Demands.Bomber);
System.out.println(plane2.identify());
MilitaryPlane plane3 = maker.make(Demands.Surveillance);
System.out.println(plane3.identify());
}
}