ファクトリパターンの目的は、DE-夫婦するいくつかのコードを、それが消費するオブジェクトの実行時の型からのもので使用することができます
// This code doesn't need to know that the factory is returning
// an object of type `com.example.parties.SurpriseParty`
AbstractParty myParty = new PartyFactory().create(...);
このようなコードを使用して、 PartyFactory
は、どのランタイムタイプを使用すべきかを正確に判断または知る責任があります。
あなたは、必要なクラスの完全修飾名を渡すことで、この利点を享受できます。どのようにこの...
// This code obviously DOES know that the factory is returning
// an object of type `com.example.parties.SurpriseParty`.
// Now only the compiler doesn't know or enforce that relationship.
AbstractParty myParty = new PartyFactory().create("com.example.parties.SurpriseParty");
...単にタイプcom.example.parties.SurpriseParty
のものとしてmyParty
を宣言すると何が違いますの?最後に、あなたのコードは同じように結合されますが、静的型の検証をやめました。これは、Javaの強力な型付けの利点のいくつかを放棄している間に、利益が得られないことを意味します。 com.example.parties.SurpriseParty
を削除してもコードはコンパイルされますが、IDEはエラーメッセージを表示せず、実行時までこのコードとcom.example.parties.SurpriseParty
の間に関係があったことを認識しません。次
// I took the liberty of renaming this class and it's only method
public class MyPartyFactory{
public Party create(String name)
{
//TODO: sanitize `name` - check it contains no `.` characters
Class c = Class.forName("com.example.parties."+name);
// I'm going to take for granted that I don't have to explain how or why `party` shouldn't be an instance variable.
Party party = (PersonalParty)c.newInstance();
return party;
}
}
:メソッドの引数は、完全修飾名単純なクラス名ではありませんので
非常に少なくとも
、私は、少なくとも、このコードを変更することをアドバイスしたい、それがに悪い習慣ですClass.forName(...)
を使用しますか?それは代替案が何であるか、そしてそれらのString
引数(name
)とこのファクトリが提供するクラスとの関係に依存します。代替案が大きな条件である場合:
if("SurpriseParty".equals(name) {
return new com.example.parties.SurpriseParty();
}
else if("GoodbyeParty".equals(name)) {
return new com.example.parties.GoodbyeParty();
}
else if("PartyOfFive".equals(name)) {
return new com.example.parties.PartyOfFive();
}
else if(/* ... */) {
// ...
}
// etc, etc etc
...これはスケーラブルではありません。このファクトリが作成する実行時の型の名前とname
引数の値の間にはっきりとした関係があるので、代わりにClass.forName
の使用を検討する必要があります。そうすれば、新しいParty
タイプをシステムに追加するたびに、Factory
オブジェクトがコード変更を必要としないように保護されます。
代わりにAbstractFactory
パターンを使用することも考えられます。あなたのかかるコードは次のようになります場合:要求され、多くの場合に発生するパーティの種類の数が限られている
AbstractParty sParty = new PartyFactory().create("SurpriseParty");
AbstractParty gbParty = new PartyFactory().create("GoodByeParty");
...、あなたが当事者のこれらの種類ごとに異なる方法を検討する必要があり:
を
...Javaの静的型付けを活用することができます。
このソリューションは、新しいタイプのParty
を追加するたびにファクトリオブジェクトを変更する必要があることを意味します。反射ソリューションかAbstractFactory
のどちらがより良い解決策であるかは、タイプParty
を追加します。新しいタイプの毎日?反射を使用します。 10年ごとに新しいパーティタイプですか? AbstractFactory
を使用してください。
これに重大な用途がありますか?一般に、私は最後の手段として反射を考慮する。特にこの目的のために。 –
アノテーションを使用するJSf2.0のようなフレームワークはどうですか?実行時にオブジェクトをインスタンス化するためにReflection APIを使用する必要がありますか? – Ullas
JSFについては、そのままタグを付けてください。 –