221

ウェブサイトからデザインパターンを読んでいました

そこで、ファクトリ、ファクトリメソッド、および抽象ファクトリについて読みましたが、それらは非常に紛らわしく、定義が明確ではありません。定義によると

ファクトリ-インスタンス化ロジックをクライアントに公開せずにオブジェクトを作成し、共通のインターフェイスを介して新しく作成されたオブジェクトを参照します。ファクトリメソッドの簡略版です

ファクトリメソッド-オブジェクトを作成するためのインターフェイスを定義しますが、サブクラスにインスタンス化するクラスを決定させ、共通のインターフェイスを介して新しく作成されたオブジェクトを参照します。

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

アブストラクトファクトリとファクトリメソッドに関する他のスタックオーバーフロースレッドも調べましたが、そこに描かれているUMLダイアグラムは、私の理解をさらに悪化させます。

誰か教えてもらえますか

  1. これらの3つのパターンは互いにどのように異なりますか?
  2. いつどちらを使用しますか?
  3. また、可能であれば、これらのパターンに関連するJavaの例はありますか?
4

9 に答える 9

316

3 つの Factory タイプはすべて同じことを行います。これらは「スマート コンストラクター」です。

Apple と Orange という 2 種類の Fruit を作成できるようにしたいとします。

工場

サブクラス化のない実装が 1 つしかないという点で、Factory は「固定」です。この場合、次のようなクラスがあります。
class FruitFactory {

  public Apple makeApple() {
    // Code for creating an Apple here.
  }

  public Orange makeOrange() {
    // Code for creating an orange here.
  }

}

ユースケース: Apple または Orange の構築は、コンストラクタで処理するには少し複雑すぎます。

工場方式

ファクトリ メソッドは一般に、クラスに一般的な処理があるが、実際に使用するフルーツの種類を変更したい場合に使用されます。そう:
abstract class FruitPicker {

  protected abstract Fruit makeFruit();

  public void pickFruit() {
    private final Fruit f = makeFruit(); // The fruit we will work on..
    <bla bla bla>
  }
}

FruitPicker.pickFruit()...次に、サブクラスでファクトリ メソッドを実装することにより、共通の機能を再利用できます。

class OrangePicker extends FruitPicker {

  @Override
  protected Fruit makeFruit() {
    return new Orange();
  }
}

抽象工場

抽象ファクトリは通常、「同じ種類」である必要があり、いくつかの共通の基本クラスを持つ必要があるオブジェクトのファミリ全体を作成できるようにする場合に、依存性注入/戦略などに使用されます。これは漠然とした果物関連の例です。ここでの使用例は、Apple で誤って OrangePicker を使用しないようにすることです。同じ工場からフルーツとピッカーを入手する限り、それらは一致します。
interface PlantFactory {
  
  Plant makePlant();

  Picker makePicker(); 

}

public class AppleFactory implements PlantFactory {
  Plant makePlant() {
    return new Apple();
  }

  Picker makePicker() {
    return new ApplePicker();
  }
}

public class OrangeFactory implements PlantFactory {
  Plant makePlant() {
    return new Orange();
  }

  Picker makePicker() {
    return new OrangePicker();
  }
}
于 2012-10-23T12:12:15.073 に答える
26
  1. これらの 3 つのパターンは互いにどのように異なるのでしょうか。

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

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

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

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

  1. いつどれを使う?

ファクトリ:クライアントはクラスを必要とするだけで、どの具象実装を取得するかは気にしません。

ファクトリ メソッド:クライアントは、実行時に作成する必要がある具体的なクラスを知りませんが、ジョブを実行するクラスを取得したいだけです。

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

抽象ファクトリ クラスは、多くの場合、ファクトリ メソッドで実装されます。ファクトリ メソッドは通常、テンプレート メソッド内で呼び出されます。

  1. また、可能であれば、これらのパターンに関連する Java の例はありますか?

ファクトリーとファクトリーメソッド

意図:

オブジェクトを作成するためのインターフェイスを定義しますが、インスタンス化するクラスはサブクラスに決定させます。Factory Method を使用すると、クラスはインスタンス化をサブクラスに任せることができます。

UML ダイアグラム:

ここに画像の説明を入力

Product: Factory メソッドが作成するオブジェクトのインターフェースを定義します。

ConcreteProduct: Product インターフェースを実装します

Creator: Factory メソッドを宣言します。

ConcreateCreator: Factory メソッドを実装して、ConcreteProduct のインスタンスを返します。

問題文: ゲーム インターフェイスを定義する Factory Methods を使用して、ゲームの Factory を作成します。

コードスニペット:

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

他の創造パターンとの比較:

  1. 設計はファクトリ メソッドを使用して開始し(複雑さが軽減され、カスタマイズ可能になり、サブクラスが急増) 、設計者が柔軟性が必要な場所を発見するにつれて、抽象ファクトリ、プロトタイプ、またはビルダー(より柔軟で複雑) に進化します。

  2. 抽象ファクトリクラスは多くの場合、ファクトリ メソッドで実装されますが、プロトタイプを使用して実装することもできます。

さらに読むための参考文献:ソースメイキングのデザインパターン

于 2016-03-07T18:41:09.290 に答える
12

すべてのデザインパターンは、記述された作業コードに触れないようにするために努力しています。作業コードに触れると、既存の作業フローに欠陥があり、何も壊れていないことを確認するために、さらに多くのテストを行う必要があることは誰もが知っています。

ファクトリパターンは入力基準に基づいてオブジェクトを作成するため、次のようなコードを記述する必要がありません。

 if (this) {
     create this kind of object 
 } else { 
     that kind of object 
 }

この良い例は旅行ウェブサイトです。旅行ウェブサイトは、旅行(フライト、電車、バス)または/およびホテルまたは/および観光名所パッケージのみを提供できます。これで、ユーザーが[次へ]を選択すると、Webサイトは作成する必要のあるオブジェクトを決定する必要があります。旅行やホテルのオブジェクトのみを作成する必要があります。

ここで、ポートフォリオに別のWebサイトを追加することを想定していて、同じコアが使用されていると思われる場合、たとえば、相乗りのWebサイトでは、タクシーを検索してオンラインで支払いを行うことができます。コアで抽象ファクトリを使用できます。このようにして、タクシーと相乗りのもう1つの工場にスナップすることができます。

両方の工場は互いに関係がないので、異なる工場に保管するのは良い設計です。

これが今はっきりしていることを願っています。この例を念頭に置いて、Webサイトをもう一度調べてください。これが、役立つことを願っています。そして、私は本当にパターンを正しく表現したことを願っています:)。

于 2012-10-23T12:05:05.780 に答える
2

元の本Design Patterns: Elements of Reusable Object-Oriented Softwareを引用した人は誰もいません。これは、セクション「作成パターンの説明」の最初の 2 つの段落で答えを示しています (強調は私のものです)。

システムが作成するオブジェクトのクラスによってシステムをパラメーター化するには、2 つの一般的な方法があります。1 つの方法は、オブジェクトを作成するクラスをサブクラス化することです。これは、Factory Method (107) パターンの使用に対応します。このアプローチの主な欠点は、製品のクラスを変更するためだけに新しいサブクラスが必要になる可能性があることです。このような変更は連鎖する可能性があります。たとえば、製品クリエーター自体がファクトリ メソッドによって作成された場合、そのクリエーターもオーバーライドする必要があります。

システムをパラメータ化するもう 1 つの方法は、オブジェクトの構成にもっと依存します。製品オブジェクトのクラスを知る責任があるオブジェクトを定義し、それをシステムのパラメータにします。これは、Abstract Factory (87)、Builder (97)、および Prototype (117) パターンの重要な側面です。3 つすべてに、製品オブジェクトの作成を担当する新しい「ファクトリ オブジェクト」の作成が含まれます。抽象ファクトリには、いくつかのクラスのオブジェクトを生成するファクトリ オブジェクトがあります。Builder には、対応する複雑なプロトコルを使用して段階的に複雑な製品を構築するファクトリ オブジェクトがあります。プロトタイプには、プロトタイプ オブジェクトをコピーして製品を構築するファクトリ オブジェクトがあります。この場合、プロトタイプは製品を返す責任があるため、ファクトリ オブジェクトとプロトタイプは同じオブジェクトです。

于 2019-11-14T10:21:41.493 に答える