【问题标题】:implement a singleton design pattern as a template将单例设计模式实现为模板
【发布时间】:2011-08-08 19:26:44
【问题描述】:

问题来了:

将单例设计模式实现为模板,这样,对于任何给定的类 Foo,您可以调用 Singleton::instance() 并获取指向单例实例的指针 Foo 类型。假设存在一个具有 acquire() 和 release() 的类 Lock 方法。如何使您的实现线程安全且异常安全?

我的分析:

正如 Joshua Bloch 在“有效的 java”中指出的那样,更好的实现方式 单例类是枚举和公共静态工厂方法。结合挥发性 和同步是我知道的使它线程安全和延迟初始化的方式 如下

public class myS{
  private static volatile final _ins = null;
  private myS(){};
  public static myS getIns(){
    synchronized(){
      if(_ins==null) _ins = new myS();
    }
    return _ins;
  }
}  

此时,我对制作单例模板有点困惑。我的理解是我们要么有一个泛型类型的接口,要么有一个抽象类。只要客户端实现它们,它们就是单例的。所以,我的猜测解决方案如下:

public interface singleton<T>{
    public T instance();
}

public class Foo implements singleton<T>{
    private static volatile final Foo _ins = null;     

    public static Foo instance(){
        synchronized(this)         
             if(_ins==null){
                _ins = new Foo();
             }
        }
    }
}

【问题讨论】:

  • 你的static instance() 方法实际上并没有实现接口的instance() 方法......这个代码和要求没有任何意义。而是研究抽象工厂和/或享元模式。
  • 我很确定这不会编译。
  • 人们一直在尝试这样做。虽然它确实保持单一职责并保持 Foo 类可测试,但所有消费类最终都与 Foo 紧密耦合。而是考虑使用 DI/IoC 容器框架。
  • 如果这是作业,请标记它。否则,可能值得分享您为什么要这样做的动机,因为手动锁定强制执行的单例是……一个坏主意。
  • 其他类如何返回单例类的实例?

标签: java multithreading design-patterns


【解决方案1】:

获得单例功能的最简单方法是使用依赖注入 (DI) 框架,例如 Spring。使用 DI 还可以获得许多其他好处。

【讨论】:

  • 能举个具体的例子吗?
  • @Component public class Foo {} 是 Spring 容器中的单例。正如其他人所说,忘记单例anti-pattern。如果您非常关心实例/生命周期管理,请使用 DI 框架。
【解决方案2】:

'singleton' 不适合'模板'。这是一种矛盾。如果您认为您最好按照以下方式实施enums

public enum MySingleton1 {

    ;

    public static void MethodA() { ... };

}

public enum MySingleton2 {

    ;

    public static int MethodB() { ... };

}

编辑

没有枚举的解决方案是:

public interface singletonMarker{};

public final class MySingleton1() extends singletonMarker {

    public static final MySingleton1 INSTANCE = new MySingleton1();

    private MySingleton1() {};

    public synchronized int mySyncMethod() { ... };

}

用法

MySingleton1.INSTANCE.mySyncMethod();

界面只是做标记,其实没必要。

【讨论】:

  • 我想你正在尝试使用:public static MySingleton# Method(){}
  • @SecureFish 不,我没有,我试图说明如何实现附加到每个单例的方法。
  • 您说的是使用实现单例类的单元素枚举类。然后我们通过mysingleton1._instance而不是mySingleton.instance()来访问它,对吧?
  • @SecureFish 不,我是说:为您需要的每个单例实现不同的枚举。通过尝试使用接口,您将实现对象暴露给各种破坏单例原则的操作。枚举消除了这些问题。它坚如磐石。
  • 但是如果不使用单元素枚举呢?
猜你喜欢
  • 1970-01-01
  • 2019-09-10
  • 2011-08-09
  • 2017-10-12
  • 1970-01-01
  • 2021-08-31
  • 1970-01-01
  • 2014-06-28
  • 1970-01-01
相关资源
最近更新 更多