单例模式的实际应用是什么?

bli*_*egz 15 c# design-patterns

重复

关于设计模式:我什么时候应该使用单身人士?

class Singleton
{
    private static Singleton instance;

    private Singleton() {}

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
                instance = new Singleton();

            return instance;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

jal*_*alf 16

简单.单身人员做什么?

  • 它提供对对象实例的全局访问,以及
  • 这保证了该类型的不超过一个实例可以不断被创建.

所以当你需要这两件事时,你就使用单身人士.

这很少见.全球通常都说不好.我们倾向于尽可能避免使用它们.并且围绕"如果存在多个实例,这是一个错误"的假设构建应用程序是危险的,因为您通常会发现假设不成立.也许您希望能够在本地创建多个实例,以用于缓存目的.也许事实证明,您需要多个数据库,多个日志,或者线程性能要求您为每个线程提供自己的实例.

在任何情况下,您都不需要强制执行"只有一个实例可能存在"的假设.如果您只需要一个实例,则只需创建一个实例.但是将构造函数保持公开可见,以便在必要时可以创建更多实例.

换句话说,单身人士提供的两个功能实际上都是负面的.一般来说,我们不希望我们的数据全局可见,我们也不想无缘无故地剥夺灵活性.

如果确实需要单例提供的功能之一,请实现一个功能,而不需要另一个功能.如果您需要全局可访问的内容,请将其设置为全局.不是单身人士.如果你确实需要强制执行只存在一个实例(我想不出你想要的任何合理的情况),那么在没有全局可见性的情况下实现它.

我所见过的唯一真实世界的单身人士应用是"建筑师已阅读GoF书籍,并决定在任何地方设计模式."或"一些陷入80年代的程序员对整体不满意"面向对象"的事情,并希望在程序代码,这意味着存储数据的全局变量.而单身听起来像一个'面向对象’的方式,使全局没有在得到大叫".

关键点在于单身人士将两个非常不同的职责混合在一起.通常,您最多只需要任何给定对象中的一个.

  • +1"Singletons听起来像一个"OOP"的方式来制作全局而不会被大喊" (2认同)

小智 8

在我的项目中,我们创建了一个记录器组件,用于将应用程序登录到不同的源(例如,基于配置的文本文件,XML和数据库).因此,有一个日志管理器,它在应用程序中创建记录器类的唯一一个实例,用于记录消息,错误等.


And*_*nea 7

Jon Skeet,THE_SKEET,有一篇很好的文章,举例说明了正确实现Singleton模式的各种方法(线程安全,懒惰,高性能).

去看看吧.


根据大众需求(呃... downvote)我重现了Skeet版本:

public sealed class Singleton
{
    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return Nested.instance;
        }
    }

    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}
Run Code Online (Sandbox Code Playgroud)

这里,实例化是由对嵌套类的静态成员的第一次引用触发的,该静态成员仅在实例中发生.这意味着实现完全是懒惰的,但具有以前的所有性能优势.请注意,尽管嵌套类可以访问封闭类的私有成员,但反之则不然,因此需要在此处为​​内部实例.但是,这并没有引起任何其他问题,因为这个类本身就是私有的.但是,为了使实例化变得懒惰,代码有点复杂.

  • 您发布的链接信息丰富,但最好扩展您的答案并在此处添加更多信息 (2认同)

Joh*_*ers 1

假设你的问题在标题中:

我曾经使用过一个 COM 对象,每个服务器只能有一个实例。我们通过单例将其公开给整个 ASP.NET 应用程序。