抽象类,所有派生的具体类应该是单例

时间:2018-03-20 08:27:07

标签: java singleton abstract-class

我正在寻找以下设计的最佳实践:我有一个抽象类,扩展该抽象类的每个具体类都应该是一个单例。

背景:具体类是收集器,用于编译和记录有关复杂遗留系统操作的统计信息。收集器可以通过静态注册表访问,因此不需要传递依赖项。抽象类提供了注册表的接口。

我知道没有提供保证的完美解决方案,必须通过惯例维护属性。尽管如此,这种情况可能有最好的做法。

3 个答案:

答案 0 :(得分:1)

从技术上讲,你不能阻止具体类允许创建它的多个实例 但是你有办法尝试从概念上强制执行它:

  • 明确说明界面

  • 设置一个约束,要求这些子类是由依赖注入容器管理的bean

答案 1 :(得分:0)

有一个解决方案可以实现这一点,它基于以下内容:

  1. 抽象类的构造函数必须具有私有可见性,因此它只能从内部实例化,并防止它在其他地方扩展。

  2. 实现单例类必须嵌套在抽象类中,并且不能是可扩展的。

  3. 实现嵌套类的实例是抽象类的静态成员。

  4. 这种方法的缺点是,由于嵌套,它很快就会变得混乱,特别是如果有很多单例实现的话。

    这可能如下所示:

    public abstract class AbstractEntity {
    
      public static final AbstractEntity SINGLETON1 = new EntityImpl1(); // might be also instantiated lazily
    
      /**
       * Private accessor will not allow this class to be extended from outside.
       */
      private AbstractEntity() {
    
      }
    
      static final class EntityImpl1 extends AbstractEntity {
    
        private EntityImpl1() {
    
        }
    
      }
    
      // other implementations...
    
    }
    

答案 2 :(得分:0)

这是我目前的解决方案

  • singleton属性由注册表管理。 JavaDoc清楚地说明了正确和预期的用途
  • 具体实例由静态register(Instance.class, Instance::new)方法注册,该方法具有类对象和该类实例的供应商作为参数
  • 注册表维护String到实例对象的映射,类对象的toString()结果为键

优点

  • 实例可以是私有的,可以放置在使用它们的类附近(即,在同一个包中)
  • 实例在第一个注册表创建一次

缺点

  • 实例由具有空参数列表
  • 的构造函数创建
  • 注册表方法需要两个参数