今天终于对设计模式中的单件模式有了一次直观的尝试,很高兴在实践中用到了传说中的设计模式。
事情的起因是这样的:在我的程序中有两个Form,其中一个主Form假定为form1,另外一个是可以在主Form中打开和关闭的form2。问题就出在这里,在form1中对form2的打开按平常的理解我们会这么写:
Code
private void button1_Click(object sender, EventArgs e)
{
//打开form2
Form2 form2=new Form2();
form2.Show();
}
private void button1_Click(object sender, EventArgs e)
{
//打开form2
Form2 form2=new Form2();
form2.Show();
}
结果,每次点击button1都会弹出一个窗口,可我实际上只需要一个窗口就行。同样,在form1的上下文菜单里我也是可以打开form2的。修改好几处涉及创建form2的代码,最后如下:
Code
private Form2 form2;
private void button1_Click(object sender, EventArgs e)
{
//打开form2
if (form2 == null || form2.IsDisposed)
{
Form2 form2=new Form2();
form2.Show();
}
}
private Form2 form2;
private void button1_Click(object sender, EventArgs e)
{
//打开form2
if (form2 == null || form2.IsDisposed)
{
Form2 form2=new Form2();
form2.Show();
}
}
OK,代码看起来没什么问题,可实际上问题来了,我又做了一个上下文菜单也可以操作打开form2,于是又把代码复制了一遍。好了,问题又来了,我需要隐藏form1,这时form2也需要隐藏,我又得判断一次“form2 == null || form2.IsDisposed”。这样判断来判断去,结果往往是忘了判断。其实问题的实质很简单:form2在程序中只能出现一次。
这种情况,我突然想到了一种模式——没错,就是单件模式。它保证了一个类只有一个实例,并提供一个访问它的全局访问点。那么,我们的form2是不是也可以设计为单件模式呢,这样就能保证在整个程序窗口中form2只出现一个。于是查找资料,修改如下:
Code
public partial class Form2 : Form
{
private static Form2 form2=null;
private Form2()
{
InitializeComponent();
}
public static Form2 GetInstance()
{
if(form2==null || form2.IsDisposed)
{
form2=new Form2();
}
return form2;
}
}
public partial class Form2 : Form
{
private static Form2 form2=null;
private Form2()
{
InitializeComponent();
}
public static Form2 GetInstance()
{
if(form2==null || form2.IsDisposed)
{
form2=new Form2();
}
return form2;
}
}
这样,在form1的代码中可以如下调用,保证了单一的form2实例:
Code
private void button1_Click(object sender, EventArgs e)
{
//打开form2
Form2.GetInstance().Show();
}
private void button1_Click(object sender, EventArgs e)
{
//打开form2
Form2.GetInstance().Show();
}
后来,继续阅读资料,发现这种写法在多线程下会出问题,明天慢慢了解。