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
![](img/factorymethod.png)
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()); } }