这篇比较好理解,就是说让类的对象实例只产生一个。

例如,老婆这个类Wife,你只能有一个实例。

在写程序时,我们可以让程序员只写一次new Wife(),这样可以只产生一个wife。

但是有些程序员不按照这个规定进行,那么我就要用机制来保障你只能有一个wife。

上代码,看看这个wife类是如何构成的。

 

public class Wife
    {
        private string name;
        private static Wife wife = new Wife();
       
        private Wife()
        {
            //不允许私自构造一个老婆
        }

        public static Wife getWife()
        {
            return wife;
        }

        public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
            }
        }
    }

只所以我们用private的构造函数,是因为不能用new去构造一个wife。

而必须用getWife()去得到一个wife。

那我们现在来测试一下,你是不是真的只能有一个老婆。

 

            Wife wife1 = Wife.getWife();
            wife1.Name = "张mm";

            Wife wife2 = Wife.getWife();
            wife2.Name = "王mm";

            Console.WriteLine("老婆1: {0}", wife1.Name);
            Console.WriteLine("老婆2: {0}", wife2.Name);

输出是:

老婆1:王mm

老婆2:王mm

奇怪,张mm哪里去了?

我们再用ReferenceEquals(object objA, object objB)这个函数来看看两个老婆一不一样

ReferenceEquals的作用是:

如果 objA 是与 objB 相同的实例,或者如果二者都为空引用,则为 ture;否则为 false

 

if (object.ReferenceEquals(wife1, wife2))
            {
                Console.WriteLine("两个老婆是一样的");
            }
            else
            {
                Console.WriteLine("两个老婆不是一样的");
            }

输出:

两个老婆是一样的

我们在声明wife2时,实际上是返回的wife1,所以这样我们就实现了单体的模式。

 

还有一种写法:

public class Wife
    {

        private string name;

        private static Wife wife = null;

        private  Wife()
        {
            //不允许私自构造一个老婆
        }

       

        public static Wife getWife()
        {

            if (wife == null)
            {
                wife = new Wife();
            }
           return wife;
        }

        public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
            }
        }

}

我们也可以看见在很多书上也是这么写的。实际上严格的说这个并不能算作是一个单体模式。

之所以这样说,这个和多线程结构有关系。

 好我们用多线程来测试一下:

Main()

{

 

System.Threading.Thread thread1 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(getYourWife));

System.Threading.Thread thread2 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(getYourWife));

thread1.Start("张mm");

thread2.Start("王mm");

}

 

private static void getYourWife(object name)
        {
            Wife wife = Wife.getWife();

            wife.Name = (string)name;

            Console.WriteLine(wife.Name);
        }

输出是:

张mm

王mm

 

恭喜你,你用这个漏洞得到了两个老婆。

那如何改进呢?

我们这个时候就要用到静态构造函数了,静态构造函数是在装载类的时候就执行。

public Class Wife

{

static Wife()
        {
        //不允许私自构造一个老婆
        wife = new Wife();
        }

        private string name;
        private static Wife wife = null;
        public static Wife getWife()
        {

           return wife;
        }

        public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
            }
        }

}