2

次のような抽象基本クラスと実装クラスがあります。

public abstract class Base
{
   public Base getInstance( Class<? extends Base> clazz )
   {
      //expected to return a singleton instance of clazz's class
   }

   public abstract absMeth();
}

public A extends Base
{
    //expected to be a singleton
}

この例では、Aをシングルトンにし、BaseでgetInstanceを記述して、呼び出しごとにAのシングルトンオブジェクトを返すことができます。これを行うと、次のようになります。

public abstract class Base
{
   public Base getInstance( Class<? extends Base> clazz )
   {
      try
      {
         return clazz.getDeclaredMethod("getInstance").invoke(null,null);
      }
   }

   public abstract void absMeth();
}

public A extends Base
{
    private static A inst;

    private A(){}

    public static A getInstance( )
    {
       if( inst!= null)
            inst = new A();
       return inst; 
    }

    public void absMeth(){
      //...
    }
}

しかし、私の懸念は、誰かが別のクラスを作成した場合class B extends Base、それもシングルトンであり、getInstanceと呼ばれる静的メソッドを必ず実装するようにするにはどうすればよいですか?

言い換えれば、クラスで拡張するすべてのクラスの仕様としてこれを強制する必要がありますBase

4

2 に答える 2

3

自分自身の単一のインスタンスを作成するように拡張するクラスを信頼することはできません1:何らかの方法ですべてが実装されていることを確認できたとしても、そのメソッド内で、自分自身の新しいインスタンスを作成する前getInstanceにチェックすることを伝える方法はありません。inst

プロセスの制御を維持します。を作成しMap<Class,Base>、リフレクション2を介して渡されたクラスをインスタンス化します。getInstanceこれで、コードは、サブクラスのに依存することなく、インスタンスを作成するかどうかを決定できます。


1よくあることわざには、「仕事を正しくやりたいのなら、自分でやりなさい」というものがあります。

2これはに基づくソリューションを説明するリンクですsetAccessible(true)

于 2012-09-07T13:36:48.713 に答える
2

シングルトンはデザインパターンであり、言語機能ではありません。構文を介して継承ツリーに強制することはほとんど不可能です。

確かに、すべてのサブクラスにメソッドを宣言して実装するように要求することは可能ですが、abstract実装の詳細を制御する方法はありません。シングルトンは、実装の詳細がすべてです。

しかし、なぜこれが懸念事項なのですか?他人のコードの内部詳細にアプリを依存させないでください。これはBadDesign™であり、この問題があることは確かな兆候です。明確に定義されたインターフェースに対してコーディングし、内部の詳細に依存しないようにします。

于 2012-09-07T13:43:03.877 に答える