二十三:抽象工場モデル


一:抽象工場モデルとは
抽象工場は工場モデルの中で最も抽象的で最も一般的な形態であり、複数の製品等級構造に直面するシステム設計である.サブシステムにはいくつかの製品オブジェクトが必要であり、これらの製品が1つ以上の製品等級構造に属していると仮定すると、これらの製品オブジェクトを消費する責任と、これらの製品オブジェクトを作成する責任を分割するために抽象工場モデルを導入することができ、このようにすると、消費製品の一方が直接製品の作成作業に参加する必要がなく、一方、共通のファクトリインタフェースに必要な製品を要求するだけである.抽象ファクトリ・モードは、次の役割に関連します.
A:抽象ファクトリ(AbstractFactory)ロール:このロールはファクトリメソッドモデルの核心であり、アプリケーションシステムのビジネスロジックとは関係なく、通常Javaインタフェースまたは抽象クラスを使用して実現されるが、すべての具体的なファクトリはこのJavaインタフェースを実現するか、この抽出クラスを継承しなければならない.
B:具体的な工場(Concrete Factory)ロール:このロールはクライアントの呼び出しの下で直接製品のインスタンスを作成し、このロールは適切な製品オブジェクトを選択するロジックを含み、このロジックはアプリケーションシステムのビジネスロジックと密接に関連しており、通常は具体的なクラスを使用してこのロールを実装する.
C:抽象製品(Abstract Product)の役割:この役割のクラスはファクトリメソッドモードで作成されたオブジェクトの親クラス、またはそれらが共有するインタフェースであり、通常はインタフェースまたは抽象クラスでこの役割を実現する.
D:具体的な製品(Concrete Porduct)ロール:抽象工場モデルによって作成されたいかなる製品オブジェクトも、クライアントが最終的に必要とするものであり、その内部にはアプリケーションシステムのビジネスロジックが満ちているに違いない.通常、具体的なクラスを使用してこのロールを実現する.
   : 
package cai.milenfan.basic.test; 

//      
public interface Creator { 
//      A     
public ProductA factoryA(); 
//      B     
public ProductB factoryB(); 
} 

package cai.milenfan.basic.test; 

public class ConcreteCreator1 implements Creator{ 

public ProductA factoryA() { 
return new ProductA1(); 
} 
public ProductB factoryB() { 
return new ProductB1(); 
} 
} 
package cai.milenfan.basic.test; 

public class ConcreteCreator2 implements Creator{ 
public ProductA factoryA() { 
return new ProductA1(); 
} 
public ProductB factoryB() { 
return new ProductB1(); 
} 
} 
package cai.milenfan.basic.test; 

public interface ProductA { 
} 
package cai.milenfan.basic.test; 

public class ProductA1 implements ProductA{ 
} 
package cai.milenfan.basic.test; 

public class ProductA2 implements ProductA{ 
} 
package cai.milenfan.basic.test; 

public interface ProductB { 
} 
package cai.milenfan.basic.test; 

public class ProductB1 implements ProductB{ 
} 
package cai.milenfan.basic.test; 

public class ProductB2 implements ProductB{ 
} 

上記の例では2つの製品等級構造があり、各製品等級構造には2つの製品、すなわち2つの製品ファミリーがあるため、工場等級構造には2つの具体的な工場(2つの製品ファミリーに対応)が現れ、各工場クラスには2つの工場方法(2つの製品等級構造に対応)がある.
二:農場システムの例を見てみましょう.
農場システムに2つの等級構造があると仮定すると、Fruit(果物)とVeggie(野菜)、および2つの製品族:TropicalとNorthernがあり、TropicalFruit(熱帯果物)、TropicalVeggie(熱帯野菜)、NorthernFruit(北方果物)、NorthernVeggie(北方野菜)の4つの製品がある.
まずGardenerインタフェースを定義します.
package cai.milenfan.basic.test; 

public interface Gardener { 
} 

NorthernGardenerとTropicalGardenerは、抽象ファクトリクラスGardererの特定のサブクラスです.つまり、これらはすべて特定のファクトリクラスです.ソースコードは次のとおりです.
package cai.milenfan.basic.test; 

public class NorthernGardener implements Gardener{ 
//       
public Fruit createFruit(String name){ 
return new NorthernFruit(name); 
} 
//       
public Viggie createViggie(String name){ 
return new NorthernViggie(); 
} 
} 
package cai.milenfan.basic.test; 

public class TropicalGardener { 
//       
public Fruit createFruit(String name){ 
return new TropicalFruit(name); 
} 
//       
public Viggie createViggie(String name){ 
return new TropicalViggie(); 
} 
} 
package cai.milenfan.basic.test; 

public interface Viggie { 
} 
package cai.milenfan.basic.test; 

public class NorthernViggie implements Viggie{ 
private String name=""; 
public NorthernViggie(){ 
} 
public String getName() { 
return name; 
} 
public void setName(String name) { 
this.name = name; 
} 
} 
package cai.milenfan.basic.test; 

public class TropicalViggie implements Viggie{ 
private String name=""; 
public TropicalViggie(){} 
public String getName() { 
return name; 
} 
public void setName(String name) { 
this.name = name; 
} 
} 
package cai.milenfan.basic.test; 

public interface Fruit { 
} 

package cai.milenfan.basic.test; 

public class NorthernFruit implements Fruit{ 
private String name=""; 
public NorthernFruit(String name){} 
public String getName() { 
return name; 
} 
public void setName(String name) { 
this.name = name; 
} 
} 
package cai.milenfan.basic.test; 

public class TropicalFruit implements Fruit{ 
private String name=""; 
public TropicalFruit(String name){} 
public String getName() { 
return name; 
} 
public void setName(String name) { 
this.name = name; 
} 
} 

使用する場合、クライアントは特定のファクトリのインスタンスを作成し、ファクトリオブジェクトのファクトリメソッドを呼び出すだけで、必要な製品オブジェクトを得ることができます.
3:このモードは“開閉”の原則に対する支持
「開閉」の原則は、1つのソフトウェアシステムが既存のコードを修正することなく、拡張によってその機能を強化する目的を達成することができることを要求し、1つの複数の製品等級構造と複数の製品ファミリーに関連するシステムに対して、その機能の強化は2つの面にほかならない.
A:新しい製品ファミリーを追加
B:新製品の等級構造を追加する
四:関連するモードとモードの実現
特定の工場クラスは、農場システムのNorthernGardenerおよびTropicalGardenerのような単一のクラスに設計することができ、1つのインスタンスであればよい.