一、定义
保证一个类仅有一个实例,并提供一个访问它的全局访问点。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。
- Singleton模式中的实例构造器可以设置为protected以允许子类派生。
- Singleton模式一般不要支持ICloneable接口,因为这可能会导致多个对象实例,与Singleton模式的初衷违背。
- Singleton模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样跟Singleton模式的初衷违背。
- Singleton模式只考虑到了对象创建的管理,并没有考虑对象销毁的管理。就支持垃圾回收的平台和对象的开销来讲,我们一般没必要对其销毁进行特殊的管理。
二、结构
创建一个 SingleObject 类。SingleObject 类有它的私有构造函数和本身的一个静态实例。
SingleObject 类提供了一个静态方法,供外界获取它的静态实例。
三、适用场景
1、要求生产唯一序列号。
2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
四、优缺点
优点:
1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
2、避免对资源的多重占用(比如写文件操作)。
缺点:
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
五、实现
单例模式的实现有多种方式
1、线程不安全
public sealed class Singleton { public int Count { get; set; } private static Singleton instance = null; public static Singleton Instance { get { if (instance == null) { instance = new Singleton(); } return instance; } } private Singleton() { Count = DateTime.Now.Millisecond; } } public class SimpleSingleton { private SimpleSingleton() { } public static readonly SimpleSingleton instance = new SimpleSingleton(); }
说明:SimpleSingleton是 Singleton 的简化版,它利用.NET的特性写的,其实和Singleton 一样
2.线程安全
/// <summary> /// 单例-线程安全 /// </summary> public sealed class SafeSingleton { public int Count { get; set; } private static SafeSingleton instance = null; private static readonly object safeLock = new object(); public static SafeSingleton Instance { get { if (instance == null) { lock (safeLock) { if (instance == null) { instance = new SafeSingleton(); } } } return instance; } } private SafeSingleton() { Count = DateTime.Now.Millisecond; } }
3.单例测试
class Program { static void Main(string[] args) { SayName(); SayNewName(); Thread.Sleep(1000); } private static async Task SayName() { await Task.Run(() => { var s = Singleton.Instance; Console.WriteLine("count:" + s.Count); var s1 = SafeSingleton.Instance; Console.WriteLine("【safe】 count:" + s1.Count); }); } private static async Task SayNewName() { await Task.Run(() => { var s = Singleton.Instance; Console.WriteLine("new count:" + s.Count); var s1 = SafeSingleton.Instance; Console.WriteLine("【safe】 new count:" + s1.Count); }); } }
结果
4、单例模式的复用
代码
/// <summary> /// 4、使用 C# 2.0 泛型来完成单例模式的重用 /// </summary> /// <typeparam name="T"></typeparam> public class SingletonProvider<T> where T : new() { SingletonProvider() { } public static T Instance { get { return SingletonCreator.instance; } } class SingletonCreator { static SingletonCreator() { } internal static readonly T instance = new T(); } } /// <summary> /// 4、业务类demo /// </summary> public class TestClass { private string _createdTimestamp; public TestClass() { _createdTimestamp = DateTime.Now.ToString(); } public void Write() { Console.WriteLine(_createdTimestamp); } } /// <summary> /// 4、范型单例示例 /// </summary> public class demo { private void dosomething() { SingletonProvider<TestClass>.Instance.Write(); } }
参考:
http://www.runoob.com/design-pattern/singleton-pattern.html
http://blog.csdn.net/dabian1987/article/details/6951652
http://blog.csdn.net/jiankunking/article/details/50867050
http://www.cnblogs.com/kmsfan/p/4562323.html
http://www.cnblogs.com/dreign/archive/2012/05/08/2490212.html(推荐)
欢迎阅读本系列文章:Head First设计模式之目录