すべてのファクトリメソッドを静的にすることはできませんか?製品を生産するものには状態が必要ですか?インスタンスファクトリまたは静的ファクトリメソッドに行くのが適切なのはいつですか?この2つを区別する例を教えてください。
「インスタンスファクトリメソッド」で実際にGoFの「ファクトリメソッド」について言っていると仮定すると、「静的ファクトリメソッド」という用語は、ジョシュアブロッホの著書「Effective Java」で説明されています。グーグルでこれらのサイトにアクセスしました:
それが違いを少し明確にするのに役立ったことを願っています。
マルボのアドバイスに従う:
オブジェクトを作成するためのインターフェースを定義しますが、インスタンス化するクラスをサブクラスに決定させます。ファクトリメソッドを使用すると、クラスはインスタンス化をサブクラスに延期できます。
例(Javaコード):
public abstract class Product { ... }
public class ConcreteProduct extends Product { ... }
public abstract class Creator {
public void anOperation() { ... product = factoryMethod(); ... }
public abstract Product factoryMethod();
}
public class ConcreteCreator extends Creator {
public Product factoryMethod() { return new ConcreteProduct(); }
}
クラスは、パブリック静的ファクトリメソッドを提供できます。これは、単にクラスのインスタンスを返す静的メソッドです。 (...)静的ファクトリメソッドの利点の1つは、コンストラクタとは異なり、名前があることです。 (...)静的ファクトリメソッドの2番目の利点は、コンストラクタとは異なり、呼び出されるたびに新しいオブジェクトを作成する必要がないことです。 (...)静的ファクトリメソッドの3番目の利点は、コンストラクタとは異なり、戻り型の任意のサブタイプのオブジェクトを返すことができることです。 (...)静的ファクトリメソッドのみを提供する主な欠点は、パブリックコンストラクターまたは保護されたコンストラクターのないクラスをサブクラス化できないことです。
例(Javaコード):
public class Boolean {
...
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
...
}
私の現在の好みは、テストを簡単にするために、ファクトリメソッドを静的ではないようにすることです。実行時に静的ファクトリメソッド呼び出しを変更することはできませんが、オブジェクトにファクトリ実装を提供できれば、コンテキストとオブジェクトグラフをより詳細に制御できるため、より徹底的にテストできます。
ファクトリからシングルトンを返す場合、ファクトリを呼び出すたびに新しいインスタンスを作成してから静的にする場合は、インスタンスが1つだけであることを確認する必要があります。
それは、たとえば、特定の量のオブジェクトのみを生成するファクトリーを持つことができます。その場合、関連付けられた状態があります。ほとんどの場合、ファクトリメソッドは、作成時に非静的変数(非静的グローバルなど)に依存しない限り、静的にすることができます。また、アプリケーションのさまざまな部分のさまざまな工場を区別する傾向があるため、工場内に状態があるかどうかに応じて、すべての工場メソッドが静的であるべきという石ではなく、どの状況が当てはまるかを確認してくださいあなたとそれを適切に書いてください。
もう1つの考慮事項はstaticキーワードです。これにより、静的なものはすべてメモリに1回だけインスタンス化されますが、欠点は常にプロセスメモリに常駐することです(ワーキングセットサイズが増加します)。工場は特定の地域で非常に高い局所性を持っている可能性があるため、これは望ましくないかもしれません。そうでなければ、メモリをどこかで使い果たしてしまいますが、これは通常、最適化の問題であり、メモリの問題アプリケーションに圧力がかかります。
以前にインスタンスが必要な場合は、静的ファクトリーを使用できます。そうでない場合は、ファクトリー自体をインスタンス化し、コードに渡します。