【问题标题】:Singleton implementation question单例实现问题
【发布时间】:2011-05-06 14:46:27
【问题描述】:

依靠IOC框架来实现单例是不是更好?听说无论是双重检查锁定还是依赖静态构造函数都不是好习惯,是这样吗?

【问题讨论】:

  • 我有点厌倦了整个“双重检查锁定不起作用”的模因。 正确实现的双重检查锁定在 .NET 中工作得很好 ...这并不是说您正朝着正确的方向前进。我倾向于尽可能避免单身;它们通常是不必要的。
  • @Andrew:OP 并没有说它不起作用。他们说他们听说这是不好的做法——我同意这一点。做对是很繁琐的,而且几乎总是有更简单的方法也能很好地工作。 (我可以依赖静态构造函数如果它做的工作相对较少,请注意。)
  • @Jon Skeet - 你是对的;不知道为什么我读到“不起作用”,而他不是这么说的。
  • @Chris:我说过volatile 可以让它工作,其他内存障碍也可以让它工作,但专家们对确切需要什么意见不一。当专家不同意时,我不会尝试提供更多关于该怎么做的信息:) 这就是我避免 DCL 的原因——它很容易出错,而且很难准确推理。我喜欢 .NET 4 中的 Lazy<T>,我相信它会做正确的事 :)
  • @Chris:我试图解释为什么我没有详细说明。至于其他内存障碍:比如调用Thread.MemoryBarrier

标签: c#


【解决方案1】:

在我看来,对象的生命周期应该由创建它的上下文决定,而不是由对象的类型强制执行。在常识中,不是保证对象“单例”的方法被认为是不好的做法,而是单例模式本身的使用。

所以,回答您的问题:是的,您应该让 IoC 容器处理其对象的生命周期。

【讨论】:

    【解决方案2】:

    也许this answer 可能对你有帮助。它包含线程安全、延迟加载的单例的基本模式。

    【讨论】:

      【解决方案3】:

      实现双重检查锁定模式非常简单,而且非常简洁和良好的做法。然而,就像@Andrew Barber 所说,不正确地实施它可能会很痛苦。

      if(_instance == null)
      {
          lock(_myLockObject)
          {
               if(_instance == null)
                  _instance = new Something();
          }
      }
      
      return _instance;
      

      【讨论】:

      • 我认为 _instance 应该声明为 volatile 才能正确。
      • 我很好奇这个。 MSDN 文档说你应该在不使用锁时使用 volatile - msdn.microsoft.com/en-us/library/x13ttww7(v=vs.71).aspx
      • 执行第一次检查时,您不在锁内。内存屏障等变得异常复杂——人们担心在发布对象中的所有数据之前发布引用的可能性。这种事情是我不喜欢的原因。
      • @Jon,我听说你不仅要声明 _instance volatile,还要声明它的所有属性 volatile。
      • @user705414:我不相信这样。
      【解决方案4】:

      作为一般规则的对象生命周期应始终由 IOC 容器处理。

      手动对象生命周期处理容易出现开发人员错误、SRP 违规和大量 DRY 违规。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-29
        相关资源
        最近更新 更多