8

これはしばらくの間私を悩ませてきましたが、これが神話であるかどうかはわかりません.

ファクトリ パターンを使用すると、クラスの依存関係を追加する手間が軽減されるようです。

例えば、ある本にこんなのがあります。

Order という名前のクラスがあるとします。最初は何にも依存していませんでした。したがって、ファクトリを使用して Order オブジェクトを作成する必要はなく、単純な new を使用してオブジェクトをインスタンス化しました。ただし、Customer に関連付けて Order を作成する必要があるという要件があります。この追加パラメーターを追加するには、何百万もの場所を変更する必要があります。Order クラスのファクトリを定義していれば、同じ苦労をせずに新しい要件を満たすことができたでしょう。

これは、コンストラクターに追加のパラメーターを追加するのと同じ苦痛ではないのはなぜですか? つまり、ファクトリに追加の引数を提供する必要があり、それは何百万もの場所でも使用されていますよね?

4

5 に答える 5

5

ユーザーがその時点でのみ認識されている場合、注文が作成さgetCurrentUser()れ、ファクトリによって呼び出される関数を実装できます。
それが可能であれば、明らかにファクトリ関数が勝ちます。そうでなければ、利益はありません。

getCurrentUser()以前は、顧客が必要とすることを知らなかったとしたら、機能を実装できるかどうかもわからなかったでしょう。ファクトリ メソッドがうまくいく可能性はあまり高くないかもしれませんが、常に 0 になるとは限りません。

于 2010-04-23T10:16:00.000 に答える
3

Factory を使用する本当の利点は、Order の役割を満たすオブジェクトを作成する方法を隠すファサードであることです。より正確には、Factory は、あなたが実際に FooBarOrder を作成していることを認識しており、常に FooBarOrder を作成することから、時々 BarFooOrder を作成することに切り替えるために、他に何も変更する必要はありません。(もし Javanewが代わりにインターセプトしてサブクラスを作ることができるなら、ファクトリは必要ないでしょう。しかし、公正であるためにはそうではないので、ファクトリを持つ必要があります。クラスのクラスをサブクラス化できるオブジェクトシステムは、この点ではより柔軟です。)

于 2010-04-23T10:03:19.903 に答える
2

いいえ、ファクトリの依存関係はファクトリ コンストラクターを介して注入する必要があり、ファクトリを 1 か所で構築するだけで、注文を作成する必要があるすべてのものへの依存関係として渡すためです。工場から注文を受けているものは、依然として同じメソッド、CreateOrder() などを呼び出しているため、コードは変更されていません。

依存関係はすべて単一の場所、構成ルートに接続する必要があり、新しい依存関係をファクトリに追加するために変更する必要がある唯一の場所である必要があります

于 2010-04-23T09:52:44.567 に答える
1

新しい依存関係についてファクトリに伝え、それを追加させます。ファクトリへのメソッド呼び出しは変更しないでください。

于 2010-04-23T09:52:30.013 に答える
1

ファクトリ パターンは、依存関係を追加する手間を軽減します。ファクトリには状態が含まれる可能性があり、実際には複数の依存関係をカプセル化できるためです (たとえば、オブジェクトのコンストラクターを呼び出すために必要な 3 つの依存関係を提供する代わりに、単一のファクトリーのみを提供するようになりました)。ファクトリには、コンストラクターに提供する必要がある 3 つのオブジェクトが含まれます)。

例を挙げると、次のように比較します。

void DoIt(const DependencyA& a, const DependencyB& b) {
   // NOTE: "x" is a contrived additional variable that we add here to
   // justify why we didn't just pass DependencyC directly.
   int x = ComputeX(); 
   std::unique_ptr<DependencyC> dependency_c(new DependencyC(a, b, x));
   dependency_c->DoStuff();
}

と:

void DoIt(const DependencyCFactory& factory) {
  int x = ComputeX();
  std::unique_ptr<DependencyC> dependency_c(factory->Create(x));
  dependency_c->DoStuff();
}

2 番目のバージョンでは、"DoIt" メソッドへの依存関係が少なくて済むことに注意してください。これは、これらの依存関係がプログラム全体で必要ないという意味ではありません (実際、プログラムはまだファクトリの実装で DependencyA と DependencyB を使用しています)。ただし、このように構造化することで、その依存関係をファクトリ コードだけに分離することができ、他のコードをよりシンプルに保ち、依存関係を簡単に変更できますDependencyC(現在、ファクトリ自体のみを更新する必要があり、すべての場所で更新する必要はありません)。インスタンス化するDependencyC)、さらに特定の安全性/セキュリティ上の利点を持つことさえできます (例: ifDependencyAおよびDependencyBデータベースのパスワードや API キーなどの機密性が高い場合、それらの使用をファクトリに制限することで、データベースや API を使用する必要があるすべての場所でこれらを渡す場合と比較して、誤った取り扱いの可能性が減少します)。

Order本に示されている例では、コンストラクターが直接使用される場所の数が減ったため、ファクトリが役立つ理由は次のとおりです。Customerファクトリを作成した 1 つの場所だけを変更して、ファクトリの追加フィールドとして格納する必要があります。ファクトリのその他の用途を変更する必要はありません。比較すると、ファクトリを使用しない場合は、コンストラクターを直接使用することが多く、Customerオブジェクトへのアクセスを何らかの方法で取得するには、コンストラクターのそれぞれを更新する必要があります。

于 2010-04-23T09:53:00.400 に答える