Java:シングルトンとジェネリックを使用した設計
質問
コレクションをふるいにかけるために使用されるPredicateというインターフェイスを使用しています。たとえば、次のように定義できます
public class BlackCatPredicate implements Predicate<Cat> {
public boolean evaluate( Cat c ) {
return c.isBlack();
}
}
そしてユーティリティfindAll( Collection<T> coll, Predicate<T> pred)
メソッドを使用して述語を猫のコレクションに適用し、黒のものだけを取得します。
これは私のコードです。コード全体に黒猫を見つけているので、BlackCatPredicateを何度もインスタンス化する必要はありません。インスタンスは1つだけです。 (シングルトン?)しかし、その後、多くの述語を作成する過程で、それぞれをシングルトンとして実装する必要はありません。では、ここでの適切な設計は何ですか?
解決
匿名クラス定数を使用し、それを操作するクラスに配置します:
public class Cat{
public static final Predicate<Cat> BLACK_PREDICATE = new Predicate<Cat>(){
public boolean evaluate( Cat c ) {
return c.isBlack();
}
};
// Rest of the Cat class goes here
}
述語にパラメーターがある場合、静的ファクトリーメソッドを使用できます。
編集:コメントで指摘されているように、使用パターンによっては、述語定数(および/またはファクトリーメソッド)を個別のクラスに収集するためのより明確なコードになる場合があります。猫だけのもの、またはそれらすべて。主にその数、追加の組織がどれだけ役立つかによります。
他のヒント
次のようなものが機能するはずです:
class Predicates
{
private static class BlackCatPredicate implements Predicate<Cat>
{
public boolean evaluate(final Cat c)
{
return c.isBlack();
}
}
private static final BlackCatPredicate = new BlackCatPredicate();
public static Predicate<Cat> getBlackCatPredicate()
{
return (blackCatPredicate);
}
}
任意の述語をarg型として受け取り、指定された述語型に対して単一のインスタンスを生成する汎用ファクトリーを作成できます。
もう1つのより一般的なアプローチは、依存性注入ライブラリの使用を開始することです。そして、それを介してすべてのオブジェクト作成を行います。通常、必要に応じて、ほとんど変更せずにタイプをシングルトンに切り替えることができます。
余分なBlackCatPredicate
インスタンスを作成する心配はまったくありません。
あちこちにnew BlackCatPredicate()
を書きたくない場合は、代わりにBlackCatPredicate.getInstance()
を書き込めるように静的ファクトリメソッドを追加できます。さらに別のオプションは、別のクラスを作成してCatPredicates.getBlackCatPredicateInstance()
を記述できるようにすることです。
ただし、これはクライアントコードからの述語の作成を抽象化するためだけであり、実際のオブジェクトの作成とは関係ありません。短命のオブジェクトを処理することは、JVMの最も優れた機能の1つです。したがって、多数の余分な<=>インスタンスを作成してすぐに破棄しても、パフォーマンスにわずかな影響はありません。