FactoryとAbstract Factoryのデザインパターンの基本的な違いは何ですか?[閉まっている]


483

ファクトリパターンと抽象ファクトリパターンの基本的な違いは何ですか?


11
私の意見では、抽象ファクトリパターンとファクトリメソッドの違いの回答の質は、ここにあるものよりもはるかに優れています。
KurzedMetal 2015年

1
主な違いは、ファクトリメソッドは継承を使用しています(間接が垂直例えばあるということであるcreateThing())と抽象ファクトリーは、組成物(間接が水平などで使用していますgetFactory().createThing()
デヴィッド・ジェームズ

1
この質問は、一部の回答者が考えているものではありません。ファクトリ、抽象ファクトリ、ファクトリメソッドの3つの異なる用語を定義するTengizの回答をお見逃しなく。
Dave Schweisguth、2016

回答:


412

Factoryパターンを使用すると、実装のインスタンス(生産AppleBananaCherry特定のインターフェイスの、など) - 、と言いますIFruit

Abstract Factoryパターンを使用すると、誰でも独自のファクトリを提供する方法を提供できます。これにより、倉庫で果物やジュースについて何も知る必要なく、倉庫をIFruitFactoryやにすることができますIJuiceFactory


5
@SPI私はあなたが私を誤解していると思います。ファクトリ自体は実装する必要はありませんIFruit- 実装するものをインスタンス化しますIFruit。もちろん、特定のインターフェースを実装するもののインスタンスを生成する必要ありません、互いにまったく関係のないものを生成するFactoryがある場合は、おそらくコードのにおいです。
John Feminella、2014

75
工場を生産する工場。我々はより深く行く必要がある...
ポール・アネコ​​フ

11
これ以上不正確なことは聞いたことがありません。抽象ファクトリー(IAbstractFactory)のインターフェースを生成するファクトリーを何と呼びますか?-ああ、そうですね、それはAbstractAbstractFactoryでしょう...
Tengiz

3
@joaquinたとえば、IFruitFactoryのファクトリが必要な場合。そして、すでに述べたように、これは完全に誤りであり、パターンに関する混乱の結果にすぎません。以下の私の答えは明確です-抽象ファクトリパターンがあり、次にファクトリメソッドパターンがあり、そして抽象ファクトリが他のファクトリのファクトリを意味すると考える混乱した人々がいます。ファクトリーは、既存のパターンを示すために使用される一般的な用語にすぎません。必要に応じて、詳細については以下の私の回答を参照してください。
Tengiz、2015年

9
これは正解です。このGoFブックによれば、抽象ファクトリーはファクトリー・インターフェースを実装するファクトリー・オブジェクトであり、具象ファクトリーを別のサブクラスと交換することができます。工場を作ることとは何の関係もありません。この回答を削除してください。誤解を招きやすく、混乱を招きます。
Lii

142

この情報のソース:http : //java.dzone.com/news/intro-design-patterns-abstract

抽象ファクトリとファクトリメソッド

抽象ファクトリのメソッドは、ファクトリメソッドとして実装されます。抽象ファクトリパターンとファクトリメソッドパターンはどちらも、抽象型とファクトリを介して、クライアントシステムを実際の実装クラスから切り離します。ファクトリメソッドは継承を通じてオブジェクトを作成し、抽象ファクトリは構成を通じてオブジェクトを作成します。

抽象ファクトリパターンは、AbstractFactory、ConcreteFactory、AbstractProduct、ConcreteProduct、およびClientで構成されます。

実装方法

抽象ファクトリパターンは、ファクトリメソッドパターン、プロトタイプパターン、またはシングルトンパターンを使用して実装できます。ConcreteFactoryオブジェクトのインスタンスは1つしか必要ないため、ConcreteFactoryオブジェクトはシングルトンとして実装できます。

ファクトリメソッドパターンは、抽象ファクトリパターンの簡略化バージョンです。ファクトリメソッドパターンは1つのファミリに属する​​製品の作成を担当しますが、抽象ファクトリパターンは複数の製品ファミリを扱います。

ファクトリメソッドは、インターフェイスと抽象クラスを使用して、クライアントをジェネレータクラスと結果の製品から分離します。抽象ファクトリーには、いくつかのファクトリー・メソッドのコンテナーであるジェネレーターと、クライアントをジェネレーターおよび製品から分離するインターフェースがあります。

ファクトリメソッドパターンを使用する場合

クライアントが使用する特定の製品からクライアントを分離する必要がある場合は、ファクトリメソッドパターンを使用します。ファクトリメソッドを使用して、製品のインスタンスを作成および構成する責任をクライアントから解放します。

抽象ファクトリパターンを使用する場合

クライアントを製品クラスから分離する必要がある場合は、抽象ファクトリパターンを使用します。プログラムの構成と変更に特に役立ちます。Abstract Factoryパターンは、どのクラスを他のクラスで使用する必要があるかについての制約を強制することもできます。新しい具体的な工場を作るのは大変な作業かもしれません。

例:

抽象ファクトリの例1

パスタメーカーでさまざまな種類のパスタを準備するためのディスクのこの仕様は、抽象ファクトリであり、特定の各ディスクがファクトリです。すべてのファクトリ(パスタメーカーディスク)は、抽象ファクトリからプロパティを継承します。個々のディスクにはパスタの作成方法に関する情報が含まれていますが、パスタメーカーには含まれていません。

抽象ファクトリの例2:

スタンピング装置は、抽象製品オブジェクトを作成する操作のインターフェースであるため、抽象ファクトリに対応します。金型はコンクリート製品を作成するため、コンクリートファクトリに対応します。各パーツカテゴリ(フード、ドアなど)は、抽象的な製品に対応しています。特定の部品(つまり、99カムリの運転席側ドア)は、コンクリート製品に対応しています。

ファクトリーメソッドの例:

おもちゃの会社は、ファクトリを使用して製品オブジェクトを作成する場合があるため、作成者に対応します。特定の種類のおもちゃ(馬または車)を製造するおもちゃ会社の部門は、ConcreteCreatorに対応します。


6
Abstract FactoryとFactory Methodを説明していただきありがとうございます。オブジェクトの作成に抽象ファクトリーでコンポジションを使用する場所と、ファクトリーメソッドで継承を使用する場所がわかりませんでした。これらを説明するコードを投稿すると非常に便利です。どうもありがとうございました。コードを待っています。再度、感謝します。
Harsha

ここでも同じですが、合成と継承のアプローチが簡単な例(ソースコード)で示されていれば、はるかに明確になります。
Aakash


構成例:パブリッククラスクライアント{AbstractProduct製品; AbstractProductAccessoriesアクセサリー。public Client(AbstractFactory factory){AbstractProduct product = factory.createProduct(); } public void run(){product.print(); アクセサリ= product.getAccessories(); }}
Asim Ghaffar 2013年

この2つのパターンのどちらが使用されたかをコードで検出することは可能ですか?
ウォーロック

98

ファクトリパターン:ファクトリはIProduct実装を生成します

抽象ファクトリパターン:ファクトリファクトリはIFactoriesを生成し、次にIFactoriesを生成します:)

【コメント通りに更新】
先ほど書いたことは、少なくともウィキペディアでは正しくありません。抽象ファクトリは、単なるファクトリインターフェースです。これにより、実行時にファクトリを切り替えて、さまざまなコンテキストでさまざまなファクトリを許可できます。例としては、OSごとに異なるファクトリ、SQLプロバイダー、ミドルウェアドライバーなどがあります。


4
いいね!抽象ファクトリーはファクトリーメソッドのセットであると言うのは正しいですか?
ウォーロック

2
私はそれは正しいと思いますが、要点も逃します:)非類似の例は、CreateBitmapFile()やCreateTextFile()などのメソッドを持つFileFactoryです。次に、そのファクトリへの参照を何らかのサービスに渡します。しかし、サービスをテストしたい場合はどうなりますか?ファイルシステムへのアクセスを模擬するには、IFileFactoryインターフェイスを作成する必要があります。さて、現実の世界では、おそらく、必要に応じてIFileFactoriesをインスタンス化するDI / IoCフレームワークがあるでしょう。この場合、IoCフレームワークが抽象ファクトリーとして機能します。
cwap 2013

5
私が正しく理解している場合、この回答は、Abstract Factoryが常にさらにIFactoriesを生成することを意味しているようです。IFactoriesはIProductsの作成に使用できます。GoFでのプレゼンテーションは、これをサポートしているようには見えず、実際には矛盾しています。AbstractFactoryのインスタンスは、IProducts自体を直接生成します。言い換えると、GoF抽象ファクトリーは「ファクトリーファクトリー」ではありませ(むしろ、その必要はありません)。
SSJ_GZ 2013年

1
抽象ファクトリパターンの定義が正しくありません。抽象ファクトリには1つ以上のファクトリメソッドが含まれ、それぞれが同じオブジェクトファミリからのインスタンスを生成します(オブジェクト階層と混同しないでください)。抽象ファクトリーファクトリーのファクトリーになることできますが、ファクトリーである必要はありません。関連商品のプロデューサーです。
GiddyUpHorsey

1
これは正解です。このGoFブックによれば、抽象ファクトリーはファクトリー・インターフェースを実装するファクトリー・オブジェクトであり、具象ファクトリーを別のサブクラスと交換することができます。工場を作ることとは何の関係もありません。この回答を削除してください。誤解を招きやすく、混乱を招きます。
Lii

42

抽象ファクトリパターン

  • 具体的クラスを指定せずに、関連オブジェクトまたは依存オブジェクトのファミリを作成するためのインターフェースを提供します。

  • 抽象ファクトリパターンは、ファクトリメソッドパターンとよく似ています。2つの違いの1つは、抽象ファクトリパターンでは、クラスがオブジェクトのインスタンス化の責任を構成を介して別のオブジェクトに委譲するのに対し、ファクトリメソッドパターンは継承を使用し、サブクラスに依存して目的のオブジェクトのインスタンス化を処理することです。

  • 実際、委任されたオブジェクトは、インスタンス化を実行するためにファクトリメソッドを頻繁に使用します。

工場パターン

  • ファクトリーパターンは創造的なパターンの例です

  • 作成パターンは、オブジェクトのインスタンス化プロセスを抽象化します。オブジェクトの作成方法を非表示にし、オブジェクトの作成方法や構成方法からシステム全体を独立させるのに役立ちます。

  • クラス作成パターンは、インスタンス化するオブジェクトを決定するための継承の使用に焦点を合わせていますFactoryメソッド

  • オブジェクト作成パターンは、別のオブジェクトへのインスタンス化の委任に焦点を当てていますAbstract Factory

参照: ファクトリvs抽象ファクトリ


3
参照リンクは
無効

39

ファクトリー・メソッド:特定の基本クラスから派生するオブジェクトを作成するファクトリーがあります

抽象ファクトリー:他のファクトリーを作成するファクトリーがあり、これらのファクトリーは基本クラスから派生したオブジェクトを作成します。これを行うのは、(Factoryメソッドのように)1つのオブジェクトを作成するだけではなく、関連するオブジェクトのコレクションを作成したい場合が多いためです。


6
これは受け入れられた回答の複製であり、同様に正しくありません。
jaco0646

36

抽象ファクトリは関連オブジェクトを作成するためのインターフェースですが、ファクトリメソッドはメソッドです。抽象ファクトリは、ファクトリメソッドによって実装されます。

ここに画像の説明を入力してください


36

基本的な違い:

ファクトリ:インスタンス化ロジックをクライアントに公開せずにオブジェクトを作成します。

ファクトリー・メソッド:オブジェクトを作成するためのインターフェースを定義しますが、インスタンス化するクラスはサブクラスに決定させます。Factoryメソッドにより、クラスはインスタンス化をサブクラスに遅らせることができます

抽象ファクトリー:具象クラスを指定せずに、関連オブジェクトまたは依存オブジェクトのファミリを作成するためのインターフェースを提供します。

AbstractFactoryパターンは、構成を使用して、Factoryメソッドの間にオブジェクトを作成する責任を別のクラスに委任しますパターンは継承を使用し、派生クラスまたはサブクラスに依存してオブジェクトを作成します

oodesignの記事から:

ファクトリクラス図:

ここに画像の説明を入力してください

例:StaticFactory

 public class ShapeFactory {

   //use getShape method to get object of type shape 
   public static Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }     
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();

      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();

      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }

      return null;
   }
}

Factoryメソッドの例を実装する非静的ファクトリーは、この投稿で入手できます。

デザインパターン:ファクトリvsファクトリメソッドvs抽象ファクトリ

いつ使用するか:クライアントはクラスを必要とするだけで、具体的な実装を気にしません。

ファクトリーメソッドクラスdigaram:

ここに画像の説明を入力してください

使用する場合:クライアントは、実行時に作成する必要がある具体的なクラスを認識していませんが、ジョブを実行するクラスを取得したいだけです。

dzoneからの抽象ファクトリクラス図

ここに画像の説明を入力してください

使用する場合:システムが製品の複数のファミリーを作成する必要がある場合、または実装の詳細を公開せずに製品のライブラリーを提供する場合。

上記の記事のソースコード例は、概念を明確に理解するのに非常に適しています。

コード例と関連するSEの質問:

工場パターン。いつファクトリーメソッドを使用するのですか?

違い:

  1. 抽象ファクトリクラスは、多くの場合、ファクトリメソッドを使用して実装されますが、プロトタイプを使用して実装することもできます。
  2. 設計はファクトリーメソッド(それほど複雑ではなく、よりカスタマイズ可能で、サブクラスが増殖する)を使用して始まり、より柔軟性が必要な他の作成パターン(より柔軟で、より複雑)に発展します。
  3. ファクトリメソッドは通常、テンプレートメソッド内で呼び出されます。

その他の役立つ記事:

ソース作成からのfactory_method

abstract_factory sourcemakingから

journaldevからのabstract-factory-design-pattern


21

抽象ファクトリーの例/シナリオ

私は梅雨の時期に雨が降り、冬は雪が降り、夏は暑く晴れる場所に住んでいます。風雨から身を守るために、違う種類の服が必要です。そのために、私は自分の家の近くの店に行き、身を守るための服やアイテムを求めます。店主から、ポケットの環境や奥行きに応じて適切なアイテムをくれました。彼がくれたアイテムは、品質と価格帯は同じです。彼は私の基準を知っているので、彼がそうするのは簡単です。しかし、通りの向こうの裕福な男が同じ要件を思い付くと、彼は高価なブランドのアイテムを手に入れます。注目すべき点の1つは、彼が私に与えたすべてのアイテムが、用語の品質、標準、およびコストで互いに補完し合うことです。彼らは一緒に行くと言うことができます。この金持ちが手に入れるアイテムも同じです。

上記のシナリオを見て、店主の効率に感謝します。この店主を抽象ショップに置き換えることができます。抽象アイテムで得られるアイテムと、パースペクティブクライアントとしての私と金持ち。私たちに必要なのは、私たちのニーズに合った製品/アイテムです。

これで、多数のクライアントに一連のサービスを提供するオンラインストアを検討している自分を簡単に見ることができます。各クライアントは、3つのグループのいずれかに属しています。プレミアムグループのユーザーがサイトを開くと、優れたUI、高度にカスタマイズされた広告ペイン、メニューのオプションなどが表示されます。これらの同じ機能セットはゴールドユーザーに提供されますが、メニューの機能は少なく、広告はほとんど関連しています。やや少ないエグノミックUI。最後は私の種類のユーザー、「無料グループ」ユーザーです。私は気分を害さないように十分に給仕されています。UIは最低限必要なものであり、広告があまりに軌道に乗っていないため、何が入っているのかわかりません。最後に、メニューにはログアウトしているだけです。

もし私がこのウェブサイトのようなものを構築する機会を得たら、私は間違いなく抽象ファクトリーパターンを検討するでしょう。

抽象製品:広告ペイン、メニュー、UIペインタ。
抽象ファクトリー:Webストアのユーザーエクスペリエンス
Concreateファクトリー:プレミアムユーザーエクスペリエンス、ゴールドユーザーエクスペリエンス、一般ユーザーエクスペリエンス。


AbstractFactoryの素晴らしいシナリオですが、実際にはファクトリーと抽象ファクトリーの違いは何であるかという質問には答えていません。
アデリン

20

多くの人が驚いたかもしれませんが、この質問は正しくありません。面接中にこの質問を聞いた場合、面接担当者が混乱の場所を理解できるようにする必要があります。

「ファクトリー」とだけ呼ばれる具体的なパターンがないことから始めましょう。「抽象ファクトリ」と呼ばれるパターンと「ファクトリメソッド」と呼ばれるパターンがあります。

では、「ファクトリー」とはどういう意味ですか?次のいずれか(参照の範囲に応じて、すべて正しいと見なすことができます):

  • Abstract Factory」のエイリアス(ショートカット)として使う人もいます。
  • ファクトリーメソッド」のエイリアス(ショートカット)として使う人もいます。
  • 一部の人々は、すべての工場/創造的なパターンのより一般的な名前としてそれを使用します。たとえば、「抽象ファクトリー」と「ファクトリーメソッド」の両方がファクトリーです。

そして、残念ながら、多くの人々は「ファクトリー」を使用して、ファクトリーまたはファクトリー(またはそれらのインターフェース)を作成する別の種類のファクトリーを示します。彼らの理論に基づいて:

Productは、AbstractFactoryによって作成されたIFactoryを実装するFactoryによって作成されたIProductを実装します。

これがどれほど愚かであるかを理解するために、方程式を続けましょう。

AbstractFactoryはIAbstractFactoryを実装します。IAbstractFactoryは... AbstractAbstractFactory ???によって作成されます。

要点をご理解いただければ幸いです。混乱しないでください。そして、理由のないものを発明しないでください。

-

PS:製品のファクトリーはAbstractFactoryであり、抽象ファクトリーのファクトリーもAbstractFactoryのもう1つの例です。


他のAbstractFactoriesを作成するAbstractFactoryを、特定のオブジェクトを作成するAbstractFactoryとどのように区別できますか?GenericAbstractFactory?またはAbstractFactoryFactory?
Andrew

デザインパターンにはそのようなものはありません。どちらもAbstractFactoryパターンのインスタンスです。つまり、1つのAbstractFactoryが特定のオブジェクトを作成し、別のAbstractFactoryがファクトリ(これもAbstractFactoryです)を作成します。
Tengiz、2015

承知しました。では、これらのクラスに名前を付けるにはどうすればよいですか?他のファクトリを作成することと他の(単純な)オブジェクトを作成することは、2つの異なるものだからです。パターンは気にしない、読みやすいコードが必要です。
Andrew

3
読み取り可能なコードは、意図を明らかにするコードです。クラスに名前を付けるときは、非常に必要でない限り、あまり多くのパターンについて言及しないでください。たとえば、さまざまなトランスポートを作成する抽象ファクトリーがある場合、それをTransportCreatorまたはTransportFactory、あるいはTransportManufacturerと呼ぶかもしれません。そして、もしあなたがこれらの工場の工場を持っているなら、あなたはそれを何であれそれを呼ぶことができます-新しいメーカーを開く人は誰でも。多分それはManufacturerManagementになることができますか?基本的に、ビジネスがそれらを呼び出すときに名前を付け、それらが実装するパターンに基づいてではありません。
Tengiz、2015

16
//Abstract factory - Provides interface to create factory of related products
interface PizzaIngredientsFactory{    
   public Dough createDough(); //Will return you family of Dough
   public Clam createClam();   //Will return you family of Clam
   public Sauce createSauce(); //Will return you family of Sauce
}

class NYPizzaIngredientsFactory implements PizzaIngredientsFactory{

   @Override
   public Dough createDough(){
      //create the concrete dough instance that NY uses
      return doughInstance;
   }

   //override other methods
} 

教科書の定義は、他の回答によってすでに提供されています。私もその例を挙げようと思いました。

これPizzaIngredientsFactory抽象ファクトリです関連する製品のファミリを作成するためのメソッドを提供です。

Abstractファクトリの各メソッドは、それ自体がFactoryメソッドであることに注意してください。Like createDough()自体は、のようなサブクラスによって具体的な実装が提供されるファクトリメソッドですNYPizzaIngredientsFactory。したがって、これを使用すると、場所ごとに、その場所に属する具体的な成分のインスタンスを作成できます。

ファクトリーメソッド

具体的な実装のインスタンスを提供します

例では:
-- createDough()生地の具体的な実装を提供します。これはファクトリーメソッドです

抽象ファクトリー

関連オブジェクトのファミリーを作成するためのインターフェースを提供します

例では:
- PizzaIngredientsFactoryそれはのようなオブジェクトの関連するセットを作成することを可能にするように抽象工場でDoughClamsSauce。オブジェクトの各ファミリを作成するために、ファクトリメソッドを提供します。

Head Firstデザインパターンの


5

私はジョンの答えに次のように貢献するいくつかのポイントがあります:

抽象工場は工場の工場です!

(ちょうど「工場」は曖昧であるため)「ファクトリメソッド」を使用すると、実装(生産LemonOrange、と言う-特定のインタフェースの、など)IFruit。このファクトリーはCitricFruitFactory

しかし、ここでCitricFruitFactoryが作成できない別の種類のフルーツを作成したいとします。多分CitricFruitFactoryあなたが作成した場合のコードは意味をなさないでしょうStrawberry(ストロベリーはクエン酸フルーツではありません!)。

あなたが呼ばれる新しい工場作成することができるようにRedFruitFactory生成しStrawberryRaspberryなど

ジョンフェミネラが言ったように 、「抽象ファクトリパターンを使用すると、特定のファクトリインターフェースの実装IFruitFactoryを作成できます。

IFruitFactoryare CitricFruitFactoryRedFruitFactory!の実装


4

:私のソースがありStackOverflowtutorialspoint.comprogrammers.stackexchange.comCodeProject.com


Factory Method(とも呼ばれますFactory)は、Interface実装のクライアントを分離するためのものです。サンプルには、Shape2つのCircleSquare実装を持つインターフェースがあります。インターフェースのType新しい関連実装などの決定パラメーターを持つファクトリー・メソッドでファクトリー・クラスを定義しましたShape


Abstract Factoryいくつかのファクトリー実装、またはいくつかのファクトリー実装によるファクトリー・インターフェースが含まれています。上記の次のサンプルでは、Color2つのRedYellow実装を持つインターフェースがあります。私たちは、定義する必要がありShapeColorFactory2とのインタフェースをRedCircleFactoryしてYellowSquareFactory。この概念を説明する次のコード:

interface ShapeColorFactory
{
    public Shape getShape();
    public Color getColor();
}

class RedCircleFactory implements ShapeColorFactory
{
    @Override
    public Shape getShape() {
        return new Circle();
    }

    @Override
    public Color getColor() {
        return new Red();
    }
}
class YellowSquareFactory implements ShapeColorFactory
{
    @Override
    public Shape getShape() {
        return new Square();
    }

    @Override
    public Color getColor() {
        return new Yellow();
    }
} 

間の違いをここにFactoryMethodしてAbstractFactoryFactory Method単にインタフェースの具象クラスを返しますが、Abstract Factoryリターンfactory of factory。つまりAbstract Factory、一連のインターフェースの異なる組み合わせを返します。


私の説明がお役に立てば幸いです。


3

これらの工場の主な違いは、工場で何をしたいのか、いつ使用したいのかです。

場合によっては、IOC(コンストラクターインジェクションなどの制御の反転)を実行しているときに、ソリッドオブジェクトを作成できることがわかります。上記の果物の例で述べたように、果物のオブジェクトを作成する準備ができている場合は、単純なファクトリパターンを使用できます。

しかし、多くの場合、ソリッドオブジェクトを作成する必要はありません。それらはプログラムフローの後半に配置されます。ただし、構成により、最初に使用するファクトリの種類がわかります。オブジェクトを作成する代わりに、共通のファクトリクラスから派生したファクトリをIOCのコンストラクタに渡すことができます。

したがって、オブジェクトの寿命と作成についても考えます。


3

どちらFactory MethodAbstract Factory具体的なタイプから切り離さクライアントを保ちます。どちらもオブジェクトを作成しますが、Factoryメソッドは継承を使用しますが、Abstract Factory使用しますが、合成を使用します。

Factory Method一方、具体物(製品)を作成するサブクラスに継承されていますAbstract Factory、関連する製品およびこれらのインタフェースのサブクラスのファミリーを作成するためのインタフェースを提供する関連製品を作成する方法を定義します。

次に、インスタンス化されたこれらのサブクラスは、抽象型として使用される製品クラスに渡されます。の関連製品は、Abstract Factoryしばしばを使用して実装されFactory Methodます。


3

John Feminellaの回答を拡張する:

AppleBananaCherry実装FruitFactoryとその呼ばれる方法があるCreateアップルやバナナやチェリーを作成する責任を負うものとします。これで、Factoryメソッドは完了です。

さて、あなたCreateはあなたの果物から特別なサラダを望んでいて、あなたの抽象工場がやって来ます。アブストラクトファクトリーは、アップル、バナナ、チェリーから特別なサラダを作る方法を知っています。

public class Apple implements Fruit, FruitFactory {
    public Fruit Create() {
        // Apple creation logic goes here
    }
}

public class Banana implements Fruit, FruitFactory {
    public Fruit Create() {
        // Banana creation logic goes here
    }
}

public class Cherry implements Fruit, FruitFactory {
    public Fruit Create() {
        // Cherry creation logic goes here
    }
}

public class SpecialSalad implements Salad, SaladFactory {
    public static Salad Create(FruitFactory[] fruits) {
        // loop through the factory and create the fruits.
        // then you're ready to cut and slice your fruits 
        // to create your special salad.
    }
}

2

定義により、2つの違いを引き出すことができます。

ファクトリ:オブジェクトを作成するためにインターフェースが使用されますが、サブクラスはインスタンス化するクラスを決定します。オブジェクトの作成は、必要なときに行われます。

抽象ファクトリ:抽象ファクトリパターンは、他のファクトリを作成するスーパーファクトリとして機能します。抽象ファクトリパターンでは、具体的なクラスを指定せずに、インターフェイスが関連オブジェクトのセット、または依存オブジェクトを作成します。

したがって、上記の定義では、特定の違いを強調できます。つまり、Factoryパターンはオブジェクトの作成を担当し、Abstract Factoryは関連するオブジェクトのセットの作成を担当します。明らかにインターフェースを介して両方。

工場パターン:

public interface IFactory{
  void VehicleType(string n);
 }

 public class Scooter : IFactory{
  public void VehicleType(string n){
   Console.WriteLine("Vehicle type: " + n);
  }
 }

 public class Bike : IFactory{
  public void VehicleType(string n) {
  Console.WriteLine("Vehicle type: " + n);
  }
 }

 public interface IVehicleFactory{
  IFactory GetVehicleType(string Vehicle);
 }

 public class ConcreteVehicleFactory : IVehicleFactory{
 public IFactory GetVehicleType(string Vehicle){
   switch (Vehicle){
    case "Scooter":
     return new Scooter();
    case "Bike":
     return new Bike();
    default:
    return new Scooter();
  }
 }

 class Program{
  static void Main(string[] args){
   IVehicleFactory factory = new ConcreteVehicleFactory();
   IFactory scooter = factory.GetVehicleType("Scooter");
   scooter.VehicleType("Scooter");

   IFactory bike = factory.GetVehicleType("Bike");
   bike.VehicleType("Bike");

   Console.ReadKey();
 }
}

抽象ファクトリパターン:

interface IVehicleFactory{
 IBike GetBike();
 IScooter GetScooter();
}

class HondaFactory : IVehicleFactory{
     public IBike GetBike(){
            return new FZS();
     }
     public IScooter GetScooter(){
            return new FZscooter();
     }
 }
class HeroFactory: IVehicleFactory{
      public IBike GetBike(){
            return new Pulsur();
     }
      public IScooter GetScooter(){
            return new PulsurScooter();
     }
}

interface IBike
    {
        string Name();
    }
interface IScooter
    {
        string Name();
    }

class FZS:IBike{
   public string Name(){
     return "FZS";
   }
}
class Pulsur:IBike{
   public string Name(){
     return "Pulsur";
   }
}

class FZscooter:IScooter {
  public string Name(){
     return "FZscooter";
   }
}

class PulsurScooter:IScooter{
  public string Name(){
     return "PulsurScooter";
   }
}

enum MANUFACTURERS
{
    HONDA,
    HERO
}

class VehicleTypeCheck{
        IBike bike;
        IScooter scooter;
        IVehicleFactory factory;
        MANUFACTURERS manu;

        public VehicleTypeCheck(MANUFACTURERS m){
            manu = m;
        }

        public void CheckProducts()
        {
            switch (manu){
                case MANUFACTURERS.HONDA:
                    factory = new HondaFactory();
                    break;
                case MANUFACTURERS.HERO:
                    factory = new HeroFactory();
                    break;
            }

      Console.WriteLine("Bike: " + factory.GetBike().Name() + "\nScooter: " +      factory.GetScooter().Name());
        }
  }

class Program
    {
        static void Main(string[] args)
        {
            VehicleTypeCheck chk = new VehicleTypeCheck(MANUFACTURERS.HONDA);
            chk.CheckProducts();

            chk= new VehicleTypeCheck(MANUFACTURERS.HERO);
            chk.CheckProducts();

            Console.Read();
        }
    }

1

ここを確認してください:http : //www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm Factoryメソッドは特定のクラス(抽象ではない)をベースクラスとして使用しているのに対し、Abstractファクトリは抽象クラスを使用しているようです。また、抽象クラスの代わりにインターフェースを使用する場合、結果は抽象ファクトリパターンの異なる実装になります。

:D


1

抽象ファクトリーは、さまざまなタイプのインターフェースを作成するためのテンプレートです。チョコレートに関する他の果物に関するデータを含むものなど、数量、価格、アイテム固有の情報を含むさまざまなタイプのcsvファイルを解析する必要があるプロジェクトがあり、解析後に、対応するデータベースでこの情報を更新する必要があるため、次のことができるようになったとします。 1つの抽象ファクトリがパーサーと修飾子ファクトリを返し、次にこのパーサーファクトリがChocolateパーサーオブジェクト、Fruit Parserオブジェクトなどを返すことができ、同様にModifier FactoryがChocolate修飾子オブジェクト、Fruit Modifierオブジェクトなどを返すことができます。


1

Java8のサンプルコードを見れば、これら2つの違いを理解できると思います。

  interface Something{}

  interface OneWhoCanProvideSomething {
     Something getSomething();
  }

  interface OneWhoCanProvideCreatorsOfSomething{
     OneWhoCanProvideSomething getCreator();
  }


public class AbstractFactoryExample {

    public static void main(String[] args) {
        //I need something
        //Let's create one
        Something something = new Something() {};

        //Or ask someone (FACTORY pattern)
        OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeA = () -> null;
        OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeB = () -> null;

        //Or ask someone who knows soemone who can create something (ABSTRACT FACTORY pattern)
        OneWhoCanProvideCreatorsOfSomething oneWhoCanProvideCreatorsOfSomething = () -> null;

        //Same thing, but you don't need to write you own interfaces
        Supplier<Something> supplierOfSomething = () -> null;
        Supplier<Supplier<Something>> supplierOfSupplier = () -> null;
    }

}

ここで問題は、どの作成方法を使用するかとその理由です。最初の方法(パターンなし、単純なコンストラクターのみ):自分で作成することはお勧めできません。すべての作業を行う必要があり、クライアントコードは特定の実装。

2番目の方法(ファクトリーパターンを使用):任意のタイプの実装を渡すことができるという利点があります。これにより、ある条件(おそらく作成メソッドに渡されるパラメーター)に基づいて異なるタイプの何かを提供できます。

3番目の方法(Abstract Factoryパターンを使用):これにより、柔軟性が向上します。ある条件(おそらく渡されたパラメーター)に基づいて、さまざまなタイプの作成者を見つけることができます。

2つの条件を組み合わせると(コードの複雑さとカップリングがわずかに増加します)、常にFactoryパターンを回避できることに注意してください。そのため、Abstract Factoryパターンの実際の使用例はめったに見られません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.