C#实现Singleton模式
任何编写过MFC应用的开发人员(不管编写的应用是如何的小)都知道什么是Singleton。Singleton是类的唯一实例。使用MFC时,从CWinApp派生的应用类的全局实例就是Singleton。当然,在MFC应用中,尽管规定不允许创建应用类的第二个实例,但是并没有什么可以阻止你那么做。在这种情况下,当你需要某个特定的类表现出Singleton行为时,一个更好的替代方案是让这个类自己负责确保只会被创建一个并且只有一个实例。再回到MFC,我们知道保证应用类实例的唯一性的责任被留给了开发应用的程序员,他(她)们必须小心不要创建应用类的第二个实例。
现在来看看下面所示的类。Singleton的访问被局限于必须通过静态方法Instance。多数情况下,Singleton应该具有全局可见性,这可通过将其创建方法public来实现。和用全局变量模拟Singleton不同,这种模式可以防止创建出多余的实例,同时兼具全局可见性。注意,该类的构造器被置为private,这就意味着没有任何办法可以绕过静态方法Instance来直接创建类的实例。
- class Singleton
- {
- private static Singleton singleton = null;
- public static Singleton Instance()
- {
- if (null == singleton)
- singleton = new Singleton();
- return singleton;
- }
- private Singleton()
- {
- }
- }
C#实现Singleton模式的作用还不止于此,尤其是可以将其扩展,以创建类的可变数量的实例。假定有一个应用,当需要执行特定任务时就需要调度一个工作者线程。考虑到节约系统资源,我们使用Singleton来实现这个线程类。不久,需要Singleton线程处理的任务变得密集起来,如果我们决定扩展这个应用,我们可以很方便地增加工作者线程的数量,因为线程的创建和对它们的访问授权的所有逻辑都被定义在一个类中。
C#实现Singleton模式的另外一个优点是Singleton的创建可以被延迟到真正需要的时候。不管是否需要,全局变量一开始就被创建,但这个全局对象并不一定是一直都需要的。C#不支持全局变量,但还是有可能在某个方法的一开始就在堆上创建了一个对象并直到很久以后才使用它。果真如此的话,Singleton模式为这种案例提供了一个优雅的解决方案。
另外,作为一个工具,在Singleton模式的实现上,C#优于C++,尽管这个优点很微妙,但绝对重要。基于C++的实现需考虑Singleton带来的一些和生命期管理有关的棘手问题,而在C#中则由运行时自动处理。这个优点是有意义的,在Singleton模式的C#实现版本中,你只需保证在需要Singleton的时候,你拥有一个活的引用即可。
C#示例:
- using System;
- class Singleton
- {
- private static Singleton singleton = null;
- public static Singleton Instance()
- {
- if (null == singleton)
- singleton = new Singleton();
- return singleton;
- }
- private Singleton()
- {
- }
- }
- class Application
- {
- public static void Main()
- {
- Singleton s1 = Singleton.Instance();
- //Singleton s2 = new Singleton(); //错误:构造器不可访问
- Singleton s2 = Singleton.Instance();
- if (s1.Equals(s2)) // 引用相等
- Console.WriteLine("Instances are identical");
- }
- }