クラスがクライアントにインスタンスを取得できるようにする通常の方法は、パブリックコンストラクターを提供することです。これを行う別の方法は、パブリック静的ファクトリメソッドを提供することです。これは、クラスのインスタンスを返す単純な静的メソッドです。静的ファクトリメソッドを使用することによる長所と短所は何ですか?
5 に答える
「EffectiveJava」という本のこの章では、それについて詳しく説明しています。コンストラクターではなく静的ファクトリーを検討してください。それはあなたが理解できる最良の方法でそれらの両方のすべての長所と短所を説明します。
本から長所と短所を引用するだけです:
利点:
- 静的ファクトリメソッドの利点の1つは、コンストラクタとは異なり、名前があることです。
- 静的ファクトリメソッドの2番目の利点は、コンストラクタとは異なり、呼び出されるたびに新しいオブジェクトを作成する必要がないことです。
- 静的ファクトリメソッドの3番目の利点は、コンストラクタとは異なり、戻り型の任意のサブタイプのオブジェクトを返すことができることです。
- 静的ファクトリメソッドの4番目の利点は、パラメータ化された型インスタンスを作成する際の冗長性が軽減されることです(これは、Java 7では無視できます)。
短所:
静的ファクトリメソッドのみを提供することの主な欠点は、パブリックコンストラクタまたは保護されたコンストラクタのないクラスをサブクラス化できないことです。
静的ファクトリメソッドの2つ目の欠点は、他の静的メソッドと簡単に区別できないことです。
あなたは私が与えたリンクでそれらをより詳細に研究することができます。
唯一の欠点は、書くコードが増えることですが、それはまだそこにあるので、ファクトリを持つためには少なくともある程度の利点が必要です。
Factoryは、常に新しいオブジェクトを返す必要はありません。これは1つの利点です。
Factoryは、必要なサブクラスをインスタンス化できます。それは別のことです。
私のプロジェクトでは、クライアントコードの見栄えを良くするために、ファクトリを追加することがよくあります。new
ファクトリメソッドに静的インポートを使用する場合、特にクラスの名前が特に簡潔でない場合は、式よりも呼び出しの方が見栄えがよくなります。これはよくあることです。
利点:-静的ファクトリメソッドの利点の1つは、コンストラクターとは異なり、名前があることです。-静的ファクトリメソッドの2番目の利点は、コンストラクタとは異なり、呼び出されるたびに新しいオブジェクトを作成する必要がないことです。-戻り型の任意のサブタイプのオブジェクトを返すことができます。短所:-静的ファクトリメソッドの主な短所は、パブリックまたは保護されたコンストラクターのないクラスをサブクラス化できないことです。-それらは他の静的メソッドと容易に区別できません。
質問の元の作者に、静的ファクトリメソッドはツールであると言います。すべてのツールと同様に、それらには、それらが最も適している用途、それらが通用する他の用途、およびそれらがあまり適応できない他の用途があります。実例を引用すると、ハンマーは釘を打ち込むのに優れており、釘を外す端で密閉された木枠をジャッキで開くのに適していますが(バールの方がはるかに優れています)、粗い表面を削るには役に立ちません。
ファクトリメソッドは、一連の作成デザインパターンの1つ、つまりオブジェクトを作成するためのパラダイムを参照します。「ビルダー」や「プロトタイプ」などの一部の作成デザインパターンでは、オブジェクト作成に新しい演算子を使用することは単に推奨されないだけでなく、全体的なデザイン目標に有害であると見なされます。人々が話す創造的なデザインパターンは...
- ファクトリメソッド
- 抽象ファクトリメソッド
- シングルトンパターン
- ビルダー
- プロトタイプ
一般的に、ファクトリメソッドは、ユーザーまたは設計者がメソッドに提供するデータに基づいて、関連するサブクラスのグループからオブジェクトを作成するために使用されます。ただし、より具体的には、静的ファクトリメソッドを使用すると、返されるオブジェクトが毎回同じである場合でも、オブジェクトの作成を制御できます。これは、たとえば、オブジェクトを作成するプロセスが時間とリソースの点で非常に高価な場合に非常に重要になる可能性があります。このような状況では、新しい演算子を使用してオブジェクトを作成すると、パフォーマンスが大幅に低下する可能性があります。
1つの解決策は、オブジェクトの再利用可能なプールを維持することです。静的ファクトリメソッドを使用することにより、アプリケーションデザイナは、空きの既存のオブジェクトが利用可能な場合にそれを返すロジックを提供できます。これにより、新しいオブジェクトを構築するための潜在的に高いコストを節約できます。これはまさに、「接続プール」を提供する接続マネージャーによるネットワークデータベース接続で行われることです。クライアントが要求を行うたびに新しいデータベース接続を構築するのではなく、接続オブジェクトは、既存のオブジェクトが利用可能な場合はそのプールから割り当てられます。これは、新しい演算子を使用すると実際にアプリケーションのパフォーマンスに悪影響を及ぼし、ソフトウェアエンジニアの設計目標を損なう状況の例です。
new演算子ではなく、ファクトリメソッドを使用してオブジェクトを作成することを検討するのに適したタイミングは次のとおりです。
- 作成されるオブジェクトは、提供されたデータに応じて作成できるオブジェクトのいくつかの可能なサブクラスの1つに属します。
- コンストラクターで可能であるよりも、オブジェクト作成プロセスをより詳細に制御するのには十分な理由があります。シングルトンデザインパターンには、静的ファクトリメソッドが必要です。
ファクトリメソッドの使用を検討するのに悪い時期は次のとおりです。
- シンプルで軽量なオブジェクト
ソフトウェア設計の問題を列挙し、それを解決するのに最適なツールを決定することがすべてです。静的ファクトリメソッドは、他のツールと同じように、あるものには適していますが、他のものにはあまり適していません。
利点の1つは、ファクトリメソッドにわかりやすい名前を付けることができることです。これは、関数内でどの関数が機能しているかを簡単に理解し、将来的にコードを保守するのに役立ちます。この例を見て、それがあなたを助けることを願っています。
public class Contact {
private Contact(String displayName, String phoneNumber, int contactType){
//do something
}
//then we will have few functon static to get constructor private
public static createContactUnknow(String phoneNumber){
return new Contact("","00000000",0);
}
public static createContactValid(String displayName, String phoneNumber, int contactType){
return new Contact(displayName, phoneNumber, contactType);
}
}
//then
Contact myGirlFriend = Contact.createContactValid("xxxx","000000",1);
Contact unknowFriend = Contact.createContactUnknow("45454545");