ファクトリパターンと抽象ファクトリパターンの基本的な違いは何ですか?
createThing()
)と抽象ファクトリーは、組成物(間接が水平などで使用していますgetFactory().createThing()
)
ファクトリパターンと抽象ファクトリパターンの基本的な違いは何ですか?
createThing()
)と抽象ファクトリーは、組成物(間接が水平などで使用していますgetFactory().createThing()
)
回答:
Factoryパターンを使用すると、実装のインスタンス(生産Apple
、Banana
、Cherry
特定のインターフェイスの、など) - 、と言いますIFruit
。
Abstract Factoryパターンを使用すると、誰でも独自のファクトリを提供する方法を提供できます。これにより、倉庫で果物やジュースについて何も知る必要なく、倉庫をIFruitFactory
やにすることができますIJuiceFactory
。
IFruit
- 実装するものをインスタンス化しますIFruit
。もちろん、特定のインターフェースを実装するもののインスタンスを生成する必要はありませんが、互いにまったく関係のないものを生成するFactoryがある場合は、おそらくコードのにおいです。
この情報のソース:http : //java.dzone.com/news/intro-design-patterns-abstract
抽象ファクトリのメソッドは、ファクトリメソッドとして実装されます。抽象ファクトリパターンとファクトリメソッドパターンはどちらも、抽象型とファクトリを介して、クライアントシステムを実際の実装クラスから切り離します。ファクトリメソッドは継承を通じてオブジェクトを作成し、抽象ファクトリは構成を通じてオブジェクトを作成します。
抽象ファクトリパターンは、AbstractFactory、ConcreteFactory、AbstractProduct、ConcreteProduct、およびClientで構成されます。
抽象ファクトリパターンは、ファクトリメソッドパターン、プロトタイプパターン、またはシングルトンパターンを使用して実装できます。ConcreteFactoryオブジェクトのインスタンスは1つしか必要ないため、ConcreteFactoryオブジェクトはシングルトンとして実装できます。
ファクトリメソッドパターンは、抽象ファクトリパターンの簡略化バージョンです。ファクトリメソッドパターンは1つのファミリに属する製品の作成を担当しますが、抽象ファクトリパターンは複数の製品ファミリを扱います。
ファクトリメソッドは、インターフェイスと抽象クラスを使用して、クライアントをジェネレータクラスと結果の製品から分離します。抽象ファクトリーには、いくつかのファクトリー・メソッドのコンテナーであるジェネレーターと、クライアントをジェネレーターおよび製品から分離するインターフェースがあります。
クライアントが使用する特定の製品からクライアントを分離する必要がある場合は、ファクトリメソッドパターンを使用します。ファクトリメソッドを使用して、製品のインスタンスを作成および構成する責任をクライアントから解放します。
クライアントを製品クラスから分離する必要がある場合は、抽象ファクトリパターンを使用します。プログラムの構成と変更に特に役立ちます。Abstract Factoryパターンは、どのクラスを他のクラスで使用する必要があるかについての制約を強制することもできます。新しい具体的な工場を作るのは大変な作業かもしれません。
パスタメーカーでさまざまな種類のパスタを準備するためのディスクのこの仕様は、抽象ファクトリであり、特定の各ディスクがファクトリです。すべてのファクトリ(パスタメーカーディスク)は、抽象ファクトリからプロパティを継承します。個々のディスクにはパスタの作成方法に関する情報が含まれていますが、パスタメーカーには含まれていません。
スタンピング装置は、抽象製品オブジェクトを作成する操作のインターフェースであるため、抽象ファクトリに対応します。金型はコンクリート製品を作成するため、コンクリートファクトリに対応します。各パーツカテゴリ(フード、ドアなど)は、抽象的な製品に対応しています。特定の部品(つまり、99カムリの運転席側ドア)は、コンクリート製品に対応しています。
おもちゃの会社は、ファクトリを使用して製品オブジェクトを作成する場合があるため、作成者に対応します。特定の種類のおもちゃ(馬または車)を製造するおもちゃ会社の部門は、ConcreteCreatorに対応します。
ファクトリパターン:ファクトリはIProduct実装を生成します
抽象ファクトリパターン:ファクトリファクトリはIFactoriesを生成し、次にIFactoriesを生成します:)
【コメント通りに更新】
先ほど書いたことは、少なくともウィキペディアでは正しくありません。抽象ファクトリは、単なるファクトリインターフェースです。これにより、実行時にファクトリを切り替えて、さまざまなコンテキストでさまざまなファクトリを許可できます。例としては、OSごとに異なるファクトリ、SQLプロバイダー、ミドルウェアドライバーなどがあります。
具体的クラスを指定せずに、関連オブジェクトまたは依存オブジェクトのファミリを作成するためのインターフェースを提供します。
抽象ファクトリパターンは、ファクトリメソッドパターンとよく似ています。2つの違いの1つは、抽象ファクトリパターンでは、クラスがオブジェクトのインスタンス化の責任を構成を介して別のオブジェクトに委譲するのに対し、ファクトリメソッドパターンは継承を使用し、サブクラスに依存して目的のオブジェクトのインスタンス化を処理することです。
実際、委任されたオブジェクトは、インスタンス化を実行するためにファクトリメソッドを頻繁に使用します。
ファクトリーパターンは創造的なパターンの例です
作成パターンは、オブジェクトのインスタンス化プロセスを抽象化します。オブジェクトの作成方法を非表示にし、オブジェクトの作成方法や構成方法からシステム全体を独立させるのに役立ちます。
クラス作成パターンは、インスタンス化するオブジェクトを決定するための継承の使用に焦点を合わせていますFactoryメソッド
オブジェクト作成パターンは、別のオブジェクトへのインスタンス化の委任に焦点を当てていますAbstract Factory
参照: ファクトリvs抽象ファクトリ
ファクトリー・メソッド:特定の基本クラスから派生するオブジェクトを作成するファクトリーがあります
抽象ファクトリー:他のファクトリーを作成するファクトリーがあり、これらのファクトリーは基本クラスから派生したオブジェクトを作成します。これを行うのは、(Factoryメソッドのように)1つのオブジェクトを作成するだけではなく、関連するオブジェクトのコレクションを作成したい場合が多いためです。
基本的な違い:
ファクトリ:インスタンス化ロジックをクライアントに公開せずにオブジェクトを作成します。
ファクトリー・メソッド:オブジェクトを作成するためのインターフェースを定義しますが、インスタンス化するクラスはサブクラスに決定させます。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:
使用する場合:クライアントは、実行時に作成する必要がある具体的なクラスを認識していませんが、ジョブを実行するクラスを取得したいだけです。
使用する場合:システムが製品の複数のファミリーを作成する必要がある場合、または実装の詳細を公開せずに製品のライブラリーを提供する場合。
上記の記事のソースコード例は、概念を明確に理解するのに非常に適しています。
コード例と関連するSEの質問:
違い:
その他の役立つ記事:
ソース作成からのfactory_method
abstract_factory sourcemakingから
journaldevからのabstract-factory-design-pattern
抽象ファクトリーの例/シナリオ
私は梅雨の時期に雨が降り、冬は雪が降り、夏は暑く晴れる場所に住んでいます。風雨から身を守るために、違う種類の服が必要です。そのために、私は自分の家の近くの店に行き、身を守るための服やアイテムを求めます。店主から、ポケットの環境や奥行きに応じて適切なアイテムをくれました。彼がくれたアイテムは、品質と価格帯は同じです。彼は私の基準を知っているので、彼がそうするのは簡単です。しかし、通りの向こうの裕福な男が同じ要件を思い付くと、彼は高価なブランドのアイテムを手に入れます。注目すべき点の1つは、彼が私に与えたすべてのアイテムが、用語の品質、標準、およびコストで互いに補完し合うことです。彼らは一緒に行くと言うことができます。この金持ちが手に入れるアイテムも同じです。
上記のシナリオを見て、店主の効率に感謝します。この店主を抽象ショップに置き換えることができます。抽象アイテムで得られるアイテムと、パースペクティブクライアントとしての私と金持ち。私たちに必要なのは、私たちのニーズに合った製品/アイテムです。
これで、多数のクライアントに一連のサービスを提供するオンラインストアを検討している自分を簡単に見ることができます。各クライアントは、3つのグループのいずれかに属しています。プレミアムグループのユーザーがサイトを開くと、優れたUI、高度にカスタマイズされた広告ペイン、メニューのオプションなどが表示されます。これらの同じ機能セットはゴールドユーザーに提供されますが、メニューの機能は少なく、広告はほとんど関連しています。やや少ないエグノミックUI。最後は私の種類のユーザー、「無料グループ」ユーザーです。私は気分を害さないように十分に給仕されています。UIは最低限必要なものであり、広告があまりに軌道に乗っていないため、何が入っているのかわかりません。最後に、メニューにはログアウトしているだけです。
もし私がこのウェブサイトのようなものを構築する機会を得たら、私は間違いなく抽象ファクトリーパターンを検討するでしょう。
抽象製品:広告ペイン、メニュー、UIペインタ。
抽象ファクトリー:Webストアのユーザーエクスペリエンス
Concreateファクトリー:プレミアムユーザーエクスペリエンス、ゴールドユーザーエクスペリエンス、一般ユーザーエクスペリエンス。
多くの人が驚いたかもしれませんが、この質問は正しくありません。面接中にこの質問を聞いた場合、面接担当者が混乱の場所を理解できるようにする必要があります。
「ファクトリー」とだけ呼ばれる具体的なパターンがないことから始めましょう。「抽象ファクトリ」と呼ばれるパターンと「ファクトリメソッド」と呼ばれるパターンがあります。
では、「ファクトリー」とはどういう意味ですか?次のいずれか(参照の範囲に応じて、すべて正しいと見なすことができます):
そして、残念ながら、多くの人々は「ファクトリー」を使用して、ファクトリーまたはファクトリー(またはそれらのインターフェース)を作成する別の種類のファクトリーを示します。彼らの理論に基づいて:
Productは、AbstractFactoryによって作成されたIFactoryを実装するFactoryによって作成されたIProductを実装します。
これがどれほど愚かであるかを理解するために、方程式を続けましょう。
AbstractFactoryはIAbstractFactoryを実装します。IAbstractFactoryは... AbstractAbstractFactory ???によって作成されます。
要点をご理解いただければ幸いです。混乱しないでください。そして、理由のないものを発明しないでください。
-
PS:製品のファクトリーはAbstractFactoryであり、抽象ファクトリーのファクトリーもAbstractFactoryのもう1つの例です。
//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
それはのようなオブジェクトの関連するセットを作成することを可能にするように抽象工場でDough
、Clams
、Sauce
。オブジェクトの各ファミリを作成するために、ファクトリメソッドを提供します。
私はジョンの答えに次のように貢献するいくつかのポイントがあります:
(ちょうど「工場」は曖昧であるため)「ファクトリメソッド」を使用すると、実装(生産Lemon
、Orange
、と言う-特定のインタフェースの、など)IFruit
。このファクトリーはCitricFruitFactory
。
しかし、ここでCitricFruitFactoryが作成できない別の種類のフルーツを作成したいとします。多分CitricFruitFactory
あなたが作成した場合のコードは意味をなさないでしょうStrawberry
(ストロベリーはクエン酸フルーツではありません!)。
あなたが呼ばれる新しい工場作成することができるようにRedFruitFactory
生成しStrawberry
、Raspberry
など
ジョンフェミネラが言ったように
、「抽象ファクトリパターンを使用すると、特定のファクトリインターフェースの実装IFruitFactory
を作成できます。
IFruitFactory
are CitricFruitFactory
とRedFruitFactory
!の実装
:私のソースがありStackOverflow
、 tutorialspoint.com
、programmers.stackexchange.com
とCodeProject.com
。
Factory Method
(とも呼ばれますFactory
)は、Interface
実装のクライアントを分離するためのものです。サンプルには、Shape
2つのCircle
とSquare
実装を持つインターフェースがあります。インターフェースのType
新しい関連実装などの決定パラメーターを持つファクトリー・メソッドでファクトリー・クラスを定義しましたShape
。
Abstract Factory
いくつかのファクトリー実装、またはいくつかのファクトリー実装によるファクトリー・インターフェースが含まれています。上記の次のサンプルでは、Color
2つのRed
とYellow
実装を持つインターフェースがあります。私たちは、定義する必要がありShapeColorFactory
2とのインタフェースを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
してAbstractFactory
。Factory Method
単にインタフェースの具象クラスを返しますが、Abstract Factory
リターンfactory of factory
。つまりAbstract Factory
、一連のインターフェースの異なる組み合わせを返します。
私の説明がお役に立てば幸いです。
これらの工場の主な違いは、工場で何をしたいのか、いつ使用したいのかです。
場合によっては、IOC(コンストラクターインジェクションなどの制御の反転)を実行しているときに、ソリッドオブジェクトを作成できることがわかります。上記の果物の例で述べたように、果物のオブジェクトを作成する準備ができている場合は、単純なファクトリパターンを使用できます。
しかし、多くの場合、ソリッドオブジェクトを作成する必要はありません。それらはプログラムフローの後半に配置されます。ただし、構成により、最初に使用するファクトリの種類がわかります。オブジェクトを作成する代わりに、共通のファクトリクラスから派生したファクトリをIOCのコンストラクタに渡すことができます。
したがって、オブジェクトの寿命と作成についても考えます。
どちらFactory Method
とAbstract Factory
具体的なタイプから切り離さクライアントを保ちます。どちらもオブジェクトを作成しますが、Factory
メソッドは継承を使用しますが、Abstract Factory
使用しますが、合成を使用します。
Factory Method
一方、具体物(製品)を作成するサブクラスに継承されていますAbstract Factory
、関連する製品およびこれらのインタフェースのサブクラスのファミリーを作成するためのインタフェースを提供する関連製品を作成する方法を定義します。
次に、インスタンス化されたこれらのサブクラスは、抽象型として使用される製品クラスに渡されます。の関連製品は、Abstract Factory
しばしばを使用して実装されFactory Method
ます。
John Feminellaの回答を拡張する:
Apple
、Banana
、Cherry
実装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つの違いを引き出すことができます。
ファクトリ:オブジェクトを作成するためにインターフェースが使用されますが、サブクラスはインスタンス化するクラスを決定します。オブジェクトの作成は、必要なときに行われます。
抽象ファクトリ:抽象ファクトリパターンは、他のファクトリを作成するスーパーファクトリとして機能します。抽象ファクトリパターンでは、具体的なクラスを指定せずに、インターフェイスが関連オブジェクトのセット、または依存オブジェクトを作成します。
したがって、上記の定義では、特定の違いを強調できます。つまり、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();
}
}
ここを確認してください:http : //www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm Factoryメソッドは特定のクラス(抽象ではない)をベースクラスとして使用しているのに対し、Abstractファクトリは抽象クラスを使用しているようです。また、抽象クラスの代わりにインターフェースを使用する場合、結果は抽象ファクトリパターンの異なる実装になります。
:D
抽象ファクトリーは、さまざまなタイプのインターフェースを作成するためのテンプレートです。チョコレートに関する他の果物に関するデータを含むものなど、数量、価格、アイテム固有の情報を含むさまざまなタイプのcsvファイルを解析する必要があるプロジェクトがあり、解析後に、対応するデータベースでこの情報を更新する必要があるため、次のことができるようになったとします。 1つの抽象ファクトリがパーサーと修飾子ファクトリを返し、次にこのパーサーファクトリがChocolateパーサーオブジェクト、Fruit Parserオブジェクトなどを返すことができ、同様にModifier FactoryがChocolate修飾子オブジェクト、Fruit Modifierオブジェクトなどを返すことができます。
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パターンの実際の使用例はめったに見られません。