1.引言
设计模式的文章,园子里很多,本人也只是在看文章,把自己的理解写下来,已加深映像。
Singleton模式要求一个类有且仅有一个实例,并且提供了一个全局的访问点。这也是一种功能的实现,比如缓存Cache,虽说有很多访问点,但是它们其实都访问的是同一个实例。
Singleton模式是用于控制创建对象,所以是一种创建型模式。
2.实战
物理模型:
实现实例唯一,很快就想到了静态变量。static变量,如果类中没有静态构造函数,该变量将在编译时就被添加到加载堆loader heap中,如果有静态构造函数,将在第一次访问类时进行初始化,初始化完成之后,就一直在loader heap中,将不会消失,是分配的这个地址不会消失,如果它指向一个对象,这个对象必然不会回收了。
public sealed class Singleton { static Singleton instance = null; }
看到上面的是sealed防止继承,如果不用静态成员,将是不安全的,因为我们无法获取一个对象的引用有多少个。我们还要保证,只实例化一次,因为等号右边的值是会变化的,如下
instance =new Singleton(); instance =null; instance =new Singleton();
上面的代码instance 变化了3个值,那是不允许的,好吧,我把构造函数给 私有化,OK防止new了,那null 怎么办,设置成只读,如属性有只读属性。如下:
public sealed class Singleton { static Singleton instance = null; Singleton() { } public static Singleton Instance { get { if (instance == null) { instance = new Singleton(); } return instance; } } }
这个 线程安全问题,多线程 可能会创建多个实例,最终 都会指向最后那个创建的对象,加锁吧。
public sealed class Singleton { static Singleton instance = null; static readonly object padlock = new object(); Singleton() { } public static Singleton Instance { get { if (instance == null) { lock (padlock) { if (instance == null) { instance = new Singleton(); } } } return instance; } } }
现在安全了,其实一个静态变量并且初始化就能达到目的,因为静态变量在内存中只有一份,它的值可以改变的,为了防止改变 只读,用readonly 修饰,不只读不行, 如下:
public sealed class Singleton { public readonly static Singleton instance = new Singleton(); }
上面方式可以不加sealed。
3.小结
实现就是用静态成员 加上 构造器的限制来进行创建,看似简单,要理解这个单例模式,这里涉及到对 继承、构造函数、sealed、readonly、static、lock 关键字的理解,单例模式体现的知识点还不少吧,这些没有理解清楚,就不能很好的实现单例模式。