一、什么是单例模式?
单例设计模式属于创建型模式范畴,所以主要用于处理对象创建和操作,当我们需要确保只创建一个特定类的实例,然后为整个应用程序提供对该实例的简单全局访问时,我们需要在C#中使用Singleton设计模式。比如:
如果使用单例模式,那在应用中的任何一个地方获取GuidService的实例来调用GetGuid方法返回的Guid都是一样的,因为所有的实例都是同一个。
二、使用单例模式的优点是什么?
在C#中使用单例设计模式的优点如下:
- 它能够处理对共享资源的并发访问。这意味着,如果我们同时与多个客户端共享一个资源,那么对该资源的并发访问将由单例设计模式很好地管理。
- 它可以是延迟加载的,并且具有静态初始化。
- 共享公共数据,即应用程序中不经常更改的主数据和配置数据。在这种情况下,我们需要在内存中缓存对象。
- 因为它提供了对特定实例的单个全局访问点,所以很容易维护。
- 减少一次又一次实例化重对象的开销。
三、单例模式实现指南
下面是在 C# 中使用单例设计模式的实现指南。
- 声明一个应该是私有且无参数的构造函数。这是必需的,因为不允许从类的外部实例化该类。它只从类中实例化。
- 该类应声明为sealed,这将确保它不能被继承。在处理嵌套类时,这将非常有用。
- 创建一个私有静态变量,该变量将保存对类的单个已创建实例的引用(如果有的话)。
- 创建一个公共静态属性/方法,该属性/方法将返回单独创建的单例类实例。此方法或属性首先检查单例类的实例是否可用。如果实例可用,那么它将返回该实例,否则它将创建一个实例,然后返回该实例。
四、C#实现单例模式案例
实现单例模式的方法有很多种,有线程安全,非安全,懒加载模式等等。如下代码:
创建的GuidService类是密封的,确保类不能被继承,并且对象实例化在派生类中受到限制。该类是使用私有构造函数创建的,该构造函数将确保该类不会从类的外部实例化。声明这个实例变量为private,并使用null值初始化它,这样可以确保基于null条件只创建类的一个实例。通过检查私有变量实例的值,公共属性GetGuidService仅用于返回类的一个实例。可以从类外部通过单例实例调用公共方法PrintDetails。
外层调用:
输出:
Counter Value 1
From Teacher
From Student
可以看到,私有构造函数只执行一次,即使调用了 GetInstance属性两次并将计数器值打印到1,因此它证明了单例实例只创建了一次。在上面的例子中,实现单例设计模式的方法不是线程安全的。这意味着在多线程环境中,它能够创建单例类的多个实例。
五、可以使用单例设计模式的实时场景
- 服务代理: 众所周知,调用 ServiceAPI 在应用程序中是一个广泛的操作。为了调用服务 API,需要花费大量时间创建服务客户端的过程。如果您将 Service 代理创建为 Singleton,那么它将提高应用程序的性能。
- 创建作为 Singleton 的数据库连接,这可以提高应用程序的性能。
- 日志: 在应用程序中,对文件执行 I/O 操作是一项开销很大的操作。如果您将 Logger 创建为 Singleton,那么它将提高 I/O 操作的性能。
- 数据共享: 如果您有任何常量值或配置值,那么您可以将这些值保存在 Singleton 中,以便应用程序的其他组件可以读取这些值。
六、使用单例模式的缺点是什么?
- 单元测试非常困难,因为它将全局状态引入到应用程序中。
- 它减少了程序内部并行的可能性,因为要访问多线程环境中的单例实例,需要使用锁定来序列化对象。