C#设计模式---单例模式

来源:互联网 发布:mac 搜狗输入法设置 编辑:程序博客网 时间:2024/06/09 17:47

夜话---设计模式‘课堂开课啦,


今天小编就来谈谈这个---单利模式

 

我们采用循序渐进的方法学习此模式。

    画两个窗体,form1上有一个butten1按钮,要求,点击butten1,打开from2 。

// form1中

private void button1_Click(object sender, EventArgs e)        {            Form2 fr = new Form2();            fr.Show();        }

这样以来,我们实现的要求的功能,但是有没有发现一个问题,每次单机butten1,都会出现一个form2窗体,之前出现的form2窗体不会消失。


怎么解决呢?很简单,单击事件发生后先判断,,,判断什么呢??

// form1中:

        private Form2 fr;        private void button1_Click(object sender, EventArgs e)        {                        if (fr==null )            {                fr = new Form2();            }                         fr.Show();        }

在窗体form2出现之前,必须先实例化form2  所以,我们判断的就是form2有没有被实例化过。。好了,现在我们刚遇到的打开多个form2.的问题解决了,,是不是很简单。


光满足于这样一个简单的东西可不行,如果现在要求form1中添加butten2按钮,同样实现打开form2的功能。。。简单,看代码:

//  form1中butten2按钮代码

 private void button2_Click(object sender, EventArgs e)        {            if (fr == null)            {                fr = new Form2();            }            fr.Show();        }

首先不说这里复制粘贴butten1的代码。。。还是先提下这个吧,复制粘贴虽然很容易,但是很没价值,如果一个有bug则需要改动就很大。不可取。。。

其次,我们来谈谈这其中的bug吧,,,运行后,打开一个form2,再关闭form2,再试试能不能打开form2????

bug出来个吧,原因是关闭form2时,他的实例没有变成null,而是变成了Disposed 所以,判断天条件需要改动。如下:

// form1中代码:

private Form2 fr;        private void button1_Click(object sender, EventArgs e)        {                        if (fr==null || fr.IsDisposed   )            {                fr = new Form2();            }                         fr.Show();        }        private void button2_Click(object sender, EventArgs e)        {            if (fr == null || fr.IsDisposed)            {                fr = new Form2();            }            fr.Show();        }

好了,这个问题又解决了。。但是,,如果我现在有很多个地方都需要实现和butten1按钮同样的功能,,,总不能还这样复制粘贴吧,,怎么解决?  把那些相同代码提取出来,放在一个方法了,当单机butten按钮时,调用这个方法就ok啦,如下:

private Form2 fr;        private void button1_Click(object sender, EventArgs e)        {              form2();        }        private void button2_Click(object sender, EventArgs e)        {               form2();        }        public void form2()        {            if (fr == null || fr.IsDisposed)            {                fr = new Form2();            }            fr.Show();        }


我看来看个题外话:

李勇某被李小某打成重伤,你说李勇某要不要报仇?他报仇的事由谁来决定呢?-----很显然,由李勇某自己决定。

再看,夫妻是否生二胎,这个由谁来决定?  当然是他们自己决定,有什么后果自己承担。

所以,现在form2是否实例化都是在form1代码里判断,这样是不是有点不妥??     应该是form2自己实例化,然后form1想用了自己调用就好了。实例化就是new的过程,问题是怎么不让form1 new呢?

试想一下,如果不对构造方法做改动恐怕不能阻止form1 new吧。。。所以,我们把实例化过程放到form2代码中,并且设置为private私有。但是这样实例化出来的对象之能在form2中使用了啊,form1无法在使用new出来的对象了。解决办法:new的过程和赋值的过程分开,然后吧赋值的过程放在form2中一个public共有方法中去,这样form1中需要使用new的实例,则可以调用该共有方法(当然,在赋值前需要判断是否为null或者disposed)这样就可以实现form2自己控制实例化过程,最重要的是实现了只 实例化一次!不会出现实例化多次而出现多个form2窗体的事情!

看代码:

//  form2中代码

public partial class Form2 : Form    {        private static Form2 fr=null ;        private  Form2()        {            InitializeComponent();        }        public static Form2 getform2()        {            if (fr ==null || fr.IsDisposed )            {                fr = new Form2();            }            return fr;        }    }

//  form1中代码

public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();        }        private void button1_Click(object sender, EventArgs e)        {            Form2.getform2().Show();        }        private void button2_Click(object sender, EventArgs e)        {            Form2.getform2().Show();        }    }

这样一来,form1不再考虑实例化的问题了,而把责任给了应该负责的类去处理,其实这就是基本的“单例模式”!


单例模式

单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。

通常我们可以让一个全局变量使得一个对象被访问,但是它不能防止你实例化多少个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且可以提供一个访问该实力的方法。



仿照上面的例题讲解改图:

Singleton 等价于form2类

-instance   等价于private static Form2 fr =null; 中的fr

 -Singleton() 等价于private form2()构造函数

+GetInstance 等价于 public static Form2 getform2()中的getform2()方法


小编好久没认真写博客了,真是抱歉,如有不妥之处还望指出督促我改进。