2010-12-28 9 views
1

私は面白いアイデアを思いついたことがあります(どのコードにも含めることはできませんが、考えるのは楽しいです)はJavaの階層構造である可能性がありますか?

多くのクラスを必要とするプログラム特定のサブクラスのこれらのクラスはすべてシングルトンである必要があります。さて、これらのクラスごとにシングルトンパターンを書くことはできますが、同じコードを何度も繰り返し書くことは無駄です。すでに共通の基底クラスがあります。これは、サブクラスから呼び出された場合、Bクラスのシングルトンを返すことをAのgetSingletonメソッドを作成するために、本当にいいだろう(簡単にするためにクラスAにキャスト)

class A{ 
    public A getSingleton(){ 
     //Wizardry 
    } 
} 
class B extends A{ 
} 

A blargh = B.getSingleton() 
A gish = B.getSingleton() 
if(A == B) 
    System.out.println("It works!") 

仕方がするように私には思えますこれは、Bのデフォルトのコンストラクタを認識して呼び出すことです(何かを渡す必要はないと仮定します)。私はJavaでの反射の黒い魔法を少し知っていますが、これができるかどうかはわかりません。

これ以上困惑する人は誰ですか?

+0

あなたはめったに本物のシングルトンを必要としません。かなりのアプリケーションでは、アプリケーションのライフサイクル中にインスタンスを1つしか持たないオブジェクトが必要な場合があります。しかし、ユニットテストを複雑にする(または防ぐ)ために、シングルトンを使うべきではないでしょう。あなたが望むものは、シングルトンに近いものですが、厳密にはそうではありません。 Springのようなフレームワークはそのような場合に役立ちます。 – SyntaxT3rr0r

+0

@Chris S. - あなたのコメントは私の答えとどう違うのですか?私たちは両方とも、シングルトンが答えではないことを示唆しています。だから、なぜ私は「助けていない」と言っているのですか? – duffymo

答えて

2

技術的には、これに似た何かを行うことができない理由はありません。 getSingletonstaticであるため(あなたはそれを宣言していないにもかかわらず)、どのクラスが呼び出されているのかを知ることができないため、正確なスキームは機能しません。それをstatic A getSingleton(Class cls)に変更すると、実行可能になる可能性があります。

しかし、これは実際には、派生クラスごとに1つのライナーgetSingletonを持つ以上の勝利ですか?スターター、あなたの1つのgetSingleton戻りAについては

ので、誰かがBのためにそれを呼び出す場合、彼らは戻ってAを取得し、Bとしてそれを使用するためにダウンキャストする必要があります。

また、スキームは正確に透明ではありません。

確かに考えるのは楽しいことですが、私はどのプロダクションシステムでもこれを行う前に、より説得力のある理由を探していきます。

0

答えは「いいえ」ではありません。

継承が "IS-A"を意味する場合、BはAであり、もはやシングルトンではありません。

私はちょうどこれを再読み込み

「...クラスの数が多い、特定のサブクラスのすべて。そして、これらのクラスのすべてが...シングルトンする必要があります」。 「多数」と「シングルトン」は矛盾していませんか?

個人的には、このようなものを維持する必要はありません。私はそれがvoted off the island at OOPSLAの近くにあったシングルトンパターンの過剰使用の例であり、過剰な巧みさを感じています。

Googleはコード内のシングルトンを特定するために、utilitiesを書いているため、削除することができます。それでもあなたにコードを捨てたいのですか?

+0

質問者の援助方法をどのように定義するかによって異なります。あなたが推奨していない何かをするのに役立つコードを投稿した場合、本当に助けていますか?私はむしろ教えて話したいと思う。 – duffymo

1

あなたはクラスを示すそのように行うことができます(彼らは公共noargsコンストラクタを持っている場合、実際にあなたがすべてのクラスのために使用することができます)

//Code not tested 
class A { 
    private static ConcurrentHashMap<Class,Object> instances=new ConcurrentHashMap(); 

    private A(){} 

    public static <T> T getInstance(Class<T extends A> classe) { 
     Object instance=instances.get(classe); 
     if(instance==null) { 
     instance=createInstance(classe,instance); 
     } 
     return instance; 
    } 

    protected <T> T createInstance(Class<T> classe) { 
     return classe.getConstructor().newInstance(); 
    } 
} 
1

それは面白いアイデアです。重複コードを減らす別の方法は、ツールを使用して "Singleton"の作成を処理することです。これをJavaで行う一般的な方法は、Springのような依存性注入ツールを使うことです。シングルトンにしたいすべての型を定義し、必要に応じてそれらの型をSpringに要求することができます。 Springでは、要求された各タイプのうちの1つだけを作成することが保証されます。コードの重複はほとんどありません。

これは、型自体にシングルトンの動作を強制しないというメリットがあります。シングルトンの問題の多くは、世界規模の国家のためにコードを効果的にテストすることがいかに難しいかを巡っています(私はかなりの時間を費やしてプロジェクトを進めてきました。 2つの異なるテストがシングルトンを変更しています)。 Springを使用すると、シングルトンのような振る舞いを得ることができますが、意味がある場合には型のインスタンスを個別に作成することもできます。