blog

最初のデザインパターン:抽象ファクトリーパターン

抽象ファクトリー・パターンは、具体的なクラスを明示的に指定することなく、関連するオブジェクトや依存するオブジェクトのファミリーを作成するためのインタフェースを提供します。 抽象ファクトリを使用すると、...

Feb 11, 2020 · 6 min. read
シェア

テキスト

I. 定義

Abstract Factory パターンは、特定のクラスを明示的に指定することなく、関連または依存するオブジェクトのファミリーを作成するためのインターフェースを提供します。

要点は

  • 抽象ファクトリにより、顧客は抽象インターフェースを使用して、実際の製品の具体的な製品を知らなくても、関連する製品のセットを作成することができます。このようにして、顧客は具体的な製品から切り離されます。
  • 抽象ファクトリーのタスクは、製品のセットを作成するインターフェイスを定義することです。このインターフェイス内の各メソッドは製品の作成を担当し、抽象ファクトリーを実装したサブクラスを使用して具体的なプラクティスを提供します。
  • 抽象ファクトリーメソッドは、多くの場合ファクトリーメソッドとして実装されます。

II. 実装ステップ

、製品抽象クラスを作成

ProductA抽象クラス

/**
 * ProductA抽象クラス
 */
public abstract class ProductA {
 
 String name;
 
 public String getName() {
 return name;
 }
}

製品B抽象クラス

/**
 * 製品B抽象クラス
 */
public abstract class ProductB {
 
 String name;
 
 public String getName() {
 return name;
 }
}

、具体的な製品を作成し、製品の抽象クラスを継承します。

製品A1

/**
 * 製品A1
 */
public class ConcreteProductA1 extends ProductA {
 
 public ConcreteProductA1() {
 name = "ConcreteProductA1";
 }
}

製品A2

/**
 * 製品A2
 */
public class ConcreteProductA2 extends ProductA {
 
 public ConcreteProductA2() {
 name = "ConcreteProductA2";
 }
}

製品B1

/**
 * 製品B1
 */
public class ConcreteProductB1 extends ProductB {
 
 public ConcreteProductB1() {
 name = "ConcreteProductB1";
 }
}

製品B2

/**
 * 製品B2
 */
public class ConcreteProductB2 extends ProductB {
 
 public ConcreteProductB2() {
 name = "ConcreteProductB2";
 }
}

、ファクトリーインターフェースを作成し、製品を作成するためのメソッドを定義します。

ファクトリー抽象クラスを使用し、具象ファクトリーを作成する際にファクトリー抽象クラスを継承することも可能です。

/**
 * 抽象工場インターフェイス
 */
public interface AbstractFactory {
 
 /**
 * 製品Aを作成する
 */
 public ProductA createProductA();
 
 /**
 * 製品Bの作成
 */
 public ProductB createProductB();
}

、特定のファクトリーを作成し、ファクトリーインターフェースを実装します。

工場1

/**
 *  
 */
public class ConcreteFactory1 implements AbstractFactory {
 @Override
 public ProductA createProductA() {
 return new ConcreteProductA1();
 }
 @Override
 public ProductB createProductB() {
 return new ConcreteProductB1();
 }
}

工場2

/**
 *  
 */
public class ConcreteFactory2 implements AbstractFactory {
 @Override
 public ProductA createProductA() {
 return new ConcreteProductA2();
 }
 @Override
 public ProductB createProductB() {
 return new ConcreteProductB2();
 }
}

、工場で製品を作る

public class Test {
 
 public static void main(String[] args) {
 //  
 AbstractFactory factory1 = new ConcreteFactory1();
 //  
 AbstractFactory factory2 = new ConcreteFactory2();
 
 // 工場1が製品を作る
 ProductA productA = factory1.createProductA();
 System.out.println("工場1が製品Aを作る" + productA.getName());
 ProductB productB = factory1.createProductB();
 System.out.println("工場1が製品Bを作る" + productB.getName());
 // 工場2が製品を作る
 productA = factory2.createProductA();
 System.out.println("工場2が製品Aを作成する" + productA.getName());
 productB = factory2.createProductB();
 System.out.println("工場2が製品Bを作る" + productB.getName());
 }
}

第三に、栗

背景

あなたがピザ屋を経営し、多くのフランチャイズ店を経営しているとします。各フランチャイズが高品質の食材を使用するようにするため、あなたは食材を生産する工場を建設し、各フランチャイズに配送することを計画しています。

フランチャイズは地域が違うので、食材も地域によって違います。そのため、地域ごとに適した食材を提供できることが重要です。

の実装

各地域に工場を建設し、各工場は対応する地域の原材料を作る責任を負います。

すべての原料抽象クラスを作成

/**
 * 生地抽象クラス
 */
public abstract class Dough {
 
 String name;
 
 public String getName() {
 return name;
 }
}
/**
 * ソース抽象クラス
 */
public abstract class Sauce {
 
 String name;
 
 public String getName() {
 return name;
 }
}
/**
 * チーズ抽象クラス
 */
public abstract class Cheese {
 
 String name;
 
 public String getName() {
 return name;
 }
}

各エリアの材料をすべて作成

/**
 * 薄皮生地
 */
public class ThinCrustDough extends Dough {
 
 public ThinCrustDough() {
 name = "Thin Crust Dough";
 }
}
/**
 * 分厚いクラスト生地
 */
public class ThickCrustDough extends Dough {
 public ThickCrustDough() {
 name = "Thick Crust Dough";
 }
}
/**
 * ガーリックケチャップ
 */
public class MarinaraSauce extends Sauce {
 public MarinaraSauce() {
 name = "Marinara Sauce";
 }
}
/**
 *  
 */
public class PlumTomatoSauce extends Sauce {
 public PlumTomatoSauce() {
 name = "Plum Tomato Sauce";
 }
}
/**
 * パルメザン・レッジャーノ
 */
public class ReggianoCheese extends Cheese{
 
 public ReggianoCheese() {
 name = "Reggiano Cheese";
 }
}
/**
 * モッツァレラチーズ
 */
public class MozzarellaCheese extends Cheese{
 public MozzarellaCheese() {
 name = "Mozzarella Cheese";
 }
}

原料工場のインターフェイスの作成

/**
 * Pizza Ingredient Factory インターフェース
 */
public interface PizzaIngredientFactory {
 
 /**
 * 生地の作成
 */
 public Dough createDough();
 
 /**
 * ソースの作成
 */
 public Sauce createSauce();
 
 /**
 * チーズの作成
 */
 public Cheese createCheese();
 
 // その他の原材料を作成する
}

各地に原料工場を設立

/**
 * ニューヨーク原料工場
 */
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
 @Override
 public Dough createDough() {
 return new ThinCrustDough();
 }
 @Override
 public Sauce createSauce() {
 return new MarinaraSauce();
 }
 @Override
 public Cheese createCheese() {
 return new ReggianoCheese();
 }
}
/**
 * シカゴ原料工場
 */
public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
 @Override
 public Dough createDough() {
 return new ThickCrustDough();
 }
 @Override
 public Sauce createSauce() {
 return new PlumTomatoSauce();
 }
 @Override
 public Cheese createCheese() {
 return new MozzarellaCheese();
 }
}

各地の原料工場を活用した原料の創出

public class Test {
 
 public static void main(String[] args) {
 // ニューヨーク原料工場
 PizzaIngredientFactory nyFactory = new NYPizzaIngredientFactory();
 // シカゴ原料工場
 PizzaIngredientFactory chicagoFactory = new ChicagoPizzaIngredientFactory();
 
 // ニューヨークの原料工場を使用して原料を作成する
 Dough dough = nyFactory.createDough();
 Sauce sauce = nyFactory.createSauce();
 Cheese cheese = nyFactory.createCheese();
 System.out.println("New York Pizza Ingredient Factory Create:");
 System.out.println(" " + dough.getName());
 System.out.println(" " + sauce.getName());
 System.out.println(" " + cheese.getName() + "
");
 // シカゴの原料工場を使用して原料を作成する
 dough = chicagoFactory.createDough();
 sauce = chicagoFactory.createSauce();
 cheese = chicagoFactory.createCheese();
 System.out.println("Chicago Pizza Ingredient Factory Create:");
 System.out.println(" " + dough.getName());
 System.out.println(" " + sauce.getName());
 System.out.println(" " + cheese.getName());
 }
}
Read next

C++プログラミング学習ノート第8章

istream: 入力操作を提供する入力ストリーム型。 cin : 標準入力からデータを読み込むistreamオブジェクト。 cout: 標準出力にデータを書き込む ostream オブジェクト。 cerr: 標準エラーにメッセージを書き込む ostream オブジェクト。 << 演算子: istream オブジェクトから入力データを読み込むために使われます。 << 演算子は

Feb 11, 2020 · 3 min read