起因:
小菜写了一个窗口程序,但是里面的那个工具箱有问题:每点击生成工具箱的按钮一次,就生成一个工具箱。这样非常不好。小菜想要的是点击一次就生成一个窗体。针对这个,大鸟就给他提出了一个模式-----单例模式。
介绍:
单例模式就是:保证一个类仅有一个实例,并且提供一个访问它的全局访问点。根据这句话,我们首先就得创建一个类,让他负责产生并保存它自己创建的 有一个唯一的实例的方法,和一个得到这个实例的方法(就是全局访问点),同时我们要做的还有设计一个方法不要让外部的代码直接实例化这个类(把这个方法写为构造方法,并且是私有的)。
举个例子:
比如一个班级只有一个班长,那么这个班长就是班这个类实例化的一个对象。同时我们不希望我们班的班长可以由任意一个班来决定,所以班这个类的生成班长的构造方法必须是私有的。这样,可以防止任何其他班级类用new来实例化一个我们班的班长。另外,“提供一个访问它的全局访问点”这句话可以理解为:既然我们不能用new来实例化班长了,我们要选出一个班长,就必须得写一个方法来执行实例化班长这个任务。那么这个方法就是全局访问点。这个方法用调用私有的构造方法来实例化一个对象。(好像有点牵强,不过本人菜鸟一个,只是就事论事)
扩展:
当多线程同时访问类时,也可能造成创造多个实例的情况,那么我们就给线程加一个锁。(用lock语句)保证在创建实例的那个全局访问点就可以只有一个进程进入执行创建实例的方法。
同时,我们还可以不用让线程每次都加锁,而是在实例没有被创建的时候再加锁处理。这种方法称为双重锁定。
另外,C#公共语言库中提供了一种“静态初始化”的方法,这种方法不需要开发人员显示地编写线程安全代码,即可解决多线程环境下它是不安全的问题。它可以在自己被加载时就将自己实例化,被形象地 称为饿汉式单例类。
而我们用的这个用公共访问点创建实例的方法,要在第一次被引用的时候才会将自己实例化,所以被称为懒汉式单例类
这两种方法各有优缺点,使用的时候可以根据情况进行合理运用。