静态类和单例模式之间存在什么实际的区别?

两者都可以在没有实例化的情况下调用,两者都只提供一个“实例”,而且都不是线程安全的。还有其他区别吗?


当前回答

Singleton的一个主要优势:多态性例如:使用Class工厂创建实例(比如基于某些配置),我们希望这个对象是真正的单实例。

其他回答

当我想要具有完整功能的类时,例如,有很多方法和变量,我使用单例;

如果我希望类中只有一个或两个方法,例如MailService类,它只有一个方法SendMail(),我使用静态类和方法。

与静态类相比,Singleton模式有几个优点。首先,单例可以扩展类和实现接口,而静态类不能(它可以扩展类,但不继承它们的实例成员)。单例可以延迟或异步初始化,而静态类通常在首次加载时初始化,这会导致潜在的类加载器问题。然而,最重要的优点是,可以在不强迫用户假设只有一个实例的情况下以多态的方式处理单态。

我同意这个定义:

单词“single”表示整个应用程序生命周期中的单个对象循环,因此范围在应用程序级别。静态不具有任何Object指针,因此作用域位于AppDomain级别。此外,两者都应实现为线程安全。

你可以发现其他有趣的区别:Singleton模式与静态类

为了说明Jon的观点,如果Logger是一个静态类,下面所示的操作是无法完成的。类SomeClass希望ILogger实现的一个实例传递到其构造函数中。

Singleton类对于实现依赖注入非常重要。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {

            var someClass = new SomeClass(Logger.GetLogger());
        }


    }

    public class SomeClass 
    {
        public SomeClass(ILogger MyLogger)
        {

        }
    }

    public class Logger : ILogger
    {
        private static Logger _logger;
        private Logger() { }

        public static Logger GetLogger()
        {
            if (_logger==null)
            {
                _logger = new Logger();
            }

            return _logger;
        }

        public void Log()
        {

        }

    }


    public interface ILogger
    {
         void Log();
    }
}

扩展Jon Skeet的答案

单例和一堆静态方法之间的最大区别是,单例可以实现接口(或从有用的基类派生,尽管这是不太常见的IME),因此您可以将单例作为“另一个”实现来传递。

当单元测试一个类时,单体更容易处理。无论您将单例作为参数(构造函数、setter或方法)传递到何处,您都可以替换单例的一个被嘲笑或存根的版本。