Factory パターンと Abstract Factory パターンの基本的な違いは何ですか?
19 に答える
Factory パターンでは、特定のインターフェイスの実装 ( Apple
、Banana
、など) のインスタンスを生成します。Cherry
IFruit
Abstract Factory パターンを使用すると、誰でも独自のファクトリを提供できるようになります。これにより、倉庫が果物やジュースについて何も知らなくてIFruitFactory
も、倉庫を にすることができます。IJuiceFactory
この情報のソース: http://java.dzone.com/news/intro-design-patterns-abstract
抽象ファクトリとファクトリ メソッド
抽象ファクトリのメソッドは、ファクトリ メソッドとして実装されます。抽象ファクトリ パターンとファクトリ メソッド パターンはどちらも、抽象型とファクトリを通じて、実際の実装クラスからクライアント システムを分離します。ファクトリ メソッドは継承によってオブジェクトを作成しますが、抽象ファクトリは合成によってオブジェクトを作成します。
抽象ファクトリ パターンは、AbstractFactory、ConcreteFactory、AbstractProduct、ConcreteProduct、および Client で構成されます。
実装方法
抽象ファクトリ パターンは、ファクトリ メソッド パターン、プロトタイプ パターン、またはシングルトン パターンを使用して実装できます。ConcreteFactory オブジェクトは、必要なインスタンスが 1 つだけであるため、Singleton として実装できます。
Factory Method パターンは、Abstract Factory パターンの単純化されたバージョンです。Factory Method パターンは、1 つのファミリーに属する製品の作成を担当しますが、Abstract Factory パターンは、複数の製品ファミリーを扱います。
Factory Method は、インターフェイスと抽象クラスを使用して、クライアントをジェネレーター クラスと結果の製品から切り離します。Abstract Factory には、いくつかのファクトリ メソッドのコンテナーであるジェネレーターと、ジェネレーターおよび製品からクライアントを切り離すインターフェイスがあります。
ファクトリ メソッド パターンを使用する場合
クライアントが使用する特定の製品からクライアントを分離する必要がある場合は、ファクトリ メソッド パターンを使用します。ファクトリ メソッドを使用して、製品のインスタンスを作成および構成する責任からクライアントを解放します。
Abstract Factory パターンを使用する場合
クライアントを製品クラスから分離する必要がある場合は、Abstract Factory パターンを使用します。プログラムの構成と変更に特に役立ちます。また、Abstract Factory パターンは、どのクラスを他のクラスと一緒に使用する必要があるかについての制約を適用することもできます。新しいコンクリート工場を作るのは大変な作業かもしれません。
例:
抽象ファクトリの例 1
パスタ メーカーでさまざまな種類のパスタを準備するためのディスクのこの仕様は、Abstract Factory であり、それぞれの特定のディスクは Factory です。すべてのファクトリ (パスタ メーカー ディスク) は、抽象的なファクトリからプロパティを継承します。個々のディスクには、パスタの作り方に関する情報が含まれていますが、パスタ メーカーには含まれていません。
抽象ファクトリの例 2:
Stamping Equipment は、抽象的な製品オブジェクトを作成する操作のインターフェイスであるため、Abstract Factory に対応します。金型は、コンクリート製品を作成するため、コンクリート ファクトリに対応します。各パーツ カテゴリ (フード、ドアなど) は、抽象的な製品に対応します。具体的な製品は特定部品(99カムリの運転席側ドアなど)に対応。
ファクトリ メソッドの例:
おもちゃ会社は、ファクトリを使用して製品オブジェクトを作成する可能性があるため、作成者に対応します。特定の種類のおもちゃ (馬または車) を製造するおもちゃ会社の部門は、ConcreteCreator に対応します。
ファクトリ パターン: ファクトリは IProduct-implementations を生成します
抽象ファクトリ パターン: factory-factory は IFactories を生成し、それが IProducts を生成します :)
[コメントに応じて更新]少なくともウィキペディア
に
よると、私が以前に書いたことは正しくありません。抽象ファクトリは単なるファクトリ インターフェイスです。これにより、実行時にファクトリを切り替えて、異なるコンテキストで異なるファクトリを許可できます。例としては、さまざまな OS、SQL プロバイダー、ミドルウェア ドライバーなどのさまざまなファクトリが考えられます。
抽象工場パターン
具象クラスを指定せずに、関連オブジェクトまたは依存オブジェクトのファミリを作成するためのインターフェイスを提供します。
抽象ファクトリ パターンは、ファクトリ メソッド パターンに非常に似ています。この 2 つの違いの 1 つは、Abstract Factory パターンでは、クラスが合成によってオブジェクトのインスタンス化の責任を別のオブジェクトに委譲するのに対し、Factory Method パターンでは継承を使用し、サブクラスに依存して目的のオブジェクトのインスタンス化を処理することです。
実際、委任されたオブジェクトは頻繁にファクトリ メソッドを使用してインスタンス化を実行します。
工場パターン
工場パターンは創造パターンの例です
作成パターンは、オブジェクトのインスタンス化プロセスを抽象化します。これらは、オブジェクトがどのように作成されるかを隠し、システム全体をそのオブジェクトの作成方法と構成方法から独立させるのに役立ちます。
クラス作成パターンは、継承を使用してインスタンス化するオブジェクトを決定することに重点を置いています Factory Method
オブジェクト作成パターンは、別のオブジェクトへのインスタンス化の委譲に焦点を当てています。
参照: ファクトリと抽象ファクトリ
ファクトリ メソッド:特定の基本クラスから派生するオブジェクトを作成するファクトリがあります。
抽象ファクトリ:他のファクトリを作成するファクトリがあり、これらのファクトリは基本クラスから派生したオブジェクトを作成します。これを行うのは、(Factory メソッドのように) 単一のオブジェクトを作成するだけでなく、関連するオブジェクトのコレクションを作成したい場合が多いためです。
基本的な違い:
Factory:インスタンス化ロジックをクライアントに公開せずにオブジェクトを作成します。
Factory Method : オブジェクトを作成するためのインターフェイスを定義しますが、インスタンス化するクラスはサブクラスに決定させます。Factory メソッドにより、クラスはインスタンス化をサブクラスに任せることができます
Abstract 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;
}
}
FactoryMethod を実装する非静的ファクトリの例は、この投稿で入手できます。
デザイン パターン: ファクトリ vs ファクトリ メソッド vs 抽象ファクトリ
いつ使用するか:クライアントはクラスを必要とするだけで、どの具象実装を取得するかは気にしません。
ファクトリメソッドクラスダイガラム:
いつ使用するか:クライアントは、実行時にどの具体的なクラスを作成する必要があるかを知りませんが、ジョブを実行するクラスを取得したいだけです。
いつ使用するか:システムで複数の製品ファミリを作成する必要がある場合、または実装の詳細を公開せずに製品のライブラリを提供する必要がある場合。
上記の記事のソース コードの例は、概念を明確に理解するのに非常に役立ちます。
関連する SE の質問とコード例:
違い:
- 抽象ファクトリ クラスは多くの場合、ファクトリ メソッドで実装されますが、プロトタイプを使用して実装することもできます。
- 設計は、ファクトリ メソッドを使用して開始し (複雑さが少なく、カスタマイズ可能で、サブクラスが増殖します)、より柔軟性が必要な他の作成パターン (より柔軟で複雑) に向かって進化します。
- ファクトリ メソッドは通常、テンプレート メソッド内で呼び出されます。
その他の役立つ記事:
ソースメイキングのfactory_method
ソースメイキングからのabstract_factory
ジャーナル開発からの抽象工場設計パターン
Abstract Factory の例/シナリオ
私は梅雨は雨が降り、冬は雪が降り、夏は晴れて暑い場所に住んでいます。風雨から身を守るために、別の種類の服が必要です。そうするために、私は家の近くの店に行き、身を守るための衣類/アイテムを求めます. 店主は私の環境と懐の深さに応じて適切なアイテムをくれます。彼が私にくれるアイテムは、同じレベルの品質と価格帯です。彼は私の基準を知っているので、そうするのは簡単です. しかし、通りの向こう側の裕福な男が同じ要件を思いついたとき、彼は高価なブランドのアイテムを手に入れました. 注目すべき点の 1 つは、彼が私にくれたすべてのアイテムが、品質、標準、コストの点で互いに補完し合っていることです。彼らはお互いに行っていると言えます。この金持ちが手に入れるアイテムも同じです。
上記のシナリオを見て、店主の効率性に感謝します。この店主をアブストラクト ショップに置き換えることができます。抽象的なアイテムと私と金持ちのクライアントとして得られるアイテム。私たちが必要とするのは、私たちのニーズに合った製品/アイテムだけです.
今では、多数のクライアントに一連のサービスを提供するオンライン ストアを検討していることを容易に理解できます。各クライアントは、3 つのグループのいずれかに属します。プレミアム グループのユーザーがサイトを開くと、優れた UI、高度にカスタマイズされた広告ペイン、メニューのオプションなどが表示されます。これらの同じ機能セットがゴールド ユーザーに提示されますが、メニューの機能は少なく、広告はほとんど関連性がありません。また、人間工学に基づいた UI はわずかに少なくなります。最後は私の種類のユーザー、「無料グループ」ユーザーです。私は気分を害さないように十分に奉仕されています。UIは最低限のもので、広告は軌道から外れているため、何が入っているのかわかりません。最後に、メニューはログアウトするだけです.
このウェブサイトのようなものを構築する機会があれば、絶対に Abstract Factory パターンを検討します。
抽象製品: 広告ペイン、メニュー、UI ペインター。
Abstract Factory : Web Store ユーザー エクスペリエンス
Concreate Factory: プレミアム ユーザー エクスペリエンス、ゴールド ユーザー エクスペリエンス、一般ユーザー エクスペリエンス。
//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 メソッドであることに注意してください。LikecreateDough()
はそれ自体がファクトリ メソッドであり、その具体的な実装は like のサブクラスによって提供されNYPizzaIngredientsFactory
ます。したがって、これを使用すると、それぞれの異なる場所で、その場所に属する具体的な成分のインスタンスを作成できます。
工場方式
具体的な実装のインスタンスを提供します
例では:
- createDough()
- 生地の具体的な実装を提供します。これはファクトリメソッドです
抽象工場
関連オブジェクトのファミリを作成するためのインターフェイスを提供します
例:
-は、 、、PizzaIngredientsFactory
などの関連するオブジェクトのセットを作成できる抽象ファクトリです。オブジェクトの各ファミリを作成するために、ファクトリ メソッドが提供されます。Dough
Clams
Sauce
次のように、ジョンの答えに貢献するポイントがいくつかあります。
抽象工場は工場の工場です!
「ファクトリ メソッド」を使用すると (「ファクトリ」だけがあいまいなため) 、特定のインターフェイスの実装 ( Lemon
、など) を生成します。この Factory は と呼ぶことができます。Orange
IFruit
CitricFruitFactory
しかし、CitricFruitFactory では作成できない別の種類の果物を作成したいと考えています。その中に を作成すると、 のコードがCitricFruitFactory
意味をなさないかもしれませStrawberry
ん (イチゴは柑橘系の果物ではありません!)。
したがって、、などRedFruitFactory
を生成するという名前の新しい Factory を作成できます。Strawberry
Raspberry
John Feminella が言ったよう
にIFruitFactory
:
その実装はIFruitFactory
ですCitricFruitFactory
とRedFruitFactory
!
両方ともFactory Method
、Abstract Factory
クライアントを具象型から分離したままにします。どちらもオブジェクトを作成しますが、Factory
メソッドは継承を使用しますが、Abstract Factory
構成を使用します。
はFactory Method
サブクラスに継承されて具体的なオブジェクト(製品)Abstract Factory
を作成しますが、関連製品のファミリを作成するためのインターフェースを提供し、これらのインターフェースのサブクラスは関連製品の作成方法を定義します。
次に、インスタンス化されたこれらのサブクラスは、抽象型として使用される製品クラスに渡されます。の関連製品は、Abstract Factory
多くの場合、 を使用して実装されFactory Method
ます。
これらのファクトリの主な違いは、ファクトリで何をしたいのか、いつそれを使用したいかということです。
IOC (コンストラクター注入などの制御の反転) を行っているときに、ソリッド オブジェクトを作成できることがわかっている場合があります。上記の果物の例で述べたように、果物のオブジェクトを作成する準備ができている場合は、単純なfactory patternを使用できます。
しかし、多くの場合、ソリッド オブジェクトを作成したくありません。ソリッド オブジェクトは、プログラム フローの後半で作成されます。ただし、構成は、オブジェクトを作成する代わりに、開始時に使用するファクトリの種類を示します。共通のファクトリ クラスから派生したファクトリを IOC のコンストラクタに渡すことができます。
ですから、オブジェクトの寿命と作成についてもそう思います。
ジョン・フェミネラの答えを拡張する:
Apple
、Banana
、Cherry
実装し、 Apple または Banana または Cherry の作成を単独で担当FruitFactory
するメソッドが呼び出されます。Create
あなたのFactory
方法で完了です。
さて、あなたCreate
は果物から特別なサラダを作りたいと思っています.Abstract Factoryが登場します. Abstract Factory は、アップル、バナナ、チェリーから特別なサラダを作成する方法を知っています。
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.
}
}
Abstract Factory は、さまざまなタイプのインターフェースを作成するためのテンプレートです。数量、価格、商品固有の情報を含むさまざまな種類の csv ファイルを解析する必要があるプロジェクトがあるとします。たとえば、果物に関するデータやチョコレートに関するデータが含まれている場合があります。解析後、対応するデータベースでこの情報を更新する必要があります。パーサーとモディファイア ファクトリを返す 1 つの抽象ファクトリで、このパーサー ファクトリはチョコレート パーサー オブジェクト、フルーツ パーサー オブジェクトなどを返すことができ、同様にモディファイア ファクトリはチョコレート モディファイア オブジェクト、フルーツ モディファイア オブジェクトなどを返すことができます。
ここを確認してください:http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm ファクトリメソッドは特定のクラス(抽象ではない)を基本クラスとして使用し、抽象ファクトリはこれに抽象クラスを使用しているようです。また、抽象クラスの代わりにインターフェイスを使用する場合、結果は抽象ファクトリ パターンの異なる実装になります。
:D