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但是没有办法控制实现细节。单例是关于实现细节的。

为什么这是一个问题呢?不要让你的应用依赖于别人代码的内部细节。这是 Bad Design™,出现此问题是一个明确的迹象。针对定义明确的接口进行编码,避免依赖内部细节。

于 2012-09-07T13:43:03.877 回答