前言
在机房重构之前。我们学习了设计模式。在这次重构中,我们的任务就是将这些模式,加入到机房的重构中去。
如今先来解决一个最简单的问题——窗口的超生。
假设不加以限制,结果会是这样:
很的不友好。那么我们怎样来解决问题呢?——单例模式。
单例模式
通常我们能够让一个全局变量使得一个对象被訪问,但他不能防止你实例化多个对象,一个最好的办法就是,让类自身保存它的唯一实例,这个类能够保证没有其它实例能够被创建。而且它能够提供一个訪问该实例的方法。
用法
在这里有两种理解。一种正确的一种错误的。
第一种
首先把声明放到类的全局变量中。然后写一个推断是否实例化过的方法,当须要该窗口显示时,调用该方法。代码例如以下:(注冊)
private frmRegister fr;//声明全局变量 private void btnRegister_Click(Object sender,EventArgs e) { openRegister(); } private void openRegister()//推断方法 { if (ftb==null || ftb.IsDisposed) { ftb =new FormToolbox(); ftb.MdiParent = this; ftb.Show(); } }
非常显然,这是一种面向过程的思维。窗口有没有被实例化,须要主窗口去推断,我们须要的是面向对象的思想。所以。这尽管能够实现单例模式的功能。但却不是单例模式。
另外一种
相同,须要声明静态类变量。可是这次是在子窗口中声明的。然后构造一个私有的方法,外部代码就不能通过new来实例化它。也就是说仅仅有该窗口才有资格实例化,最后在该类中写静态方法。代码例如以下:
Public partial class frmRegister:Form { private static frmRegister fr=null;//<span style="font-size:18px;">声明静态类变量</span> private frmRegister()//<span style="font-size:18px;">构造一个私有的方法</span> { InitializeComponent(); } public static frmRegister GetInstance()//静态的类方法,返回值就是该类的实例 { if (fr == null || fr.IsDisposed) { fr = new frmRegister(); fr.MdiParent = MDIfrmMain.ActiveForm; } return fr; } }
这样,我们在client调用时。仅仅须要写:frmRegister.GetInstance().Show();就能够了。client不用做不论什么工作,仅仅是在须要的时候调用一下方法就能够了。并且外部不能通过new来实例化这个窗口。由于这个窗口仅仅有一个实例化,被这个类自己保存着。
调用方法时类会推断有没有被实例化过,假设没有。则实例化一个返回,假设有,则直接返回。
机房中的单例模式
尽管第一种方法不符合面向对象。可是我为什么要写它呢?这就和我的机房有点关系。大家都知道,机房收费系统的主界面有一张图片。这就须要一个转换容器的api函数去做对应的转换,这样一来。单例模式在实际中的应用就要多点东西,也就是在每个子窗口上都加上引用。然后在每个窗口中去做调换,我觉得这是相当麻烦而且也不是一个好办法,所以。在重复比較下,我选择了之前相对错误的做法。将推断的权利交给主窗口。
总结
一个模式的应用并非死板的,在对的时候用对的模式,不拘泥于模式的格式,如何使系统做起来更简单,更好用。就如何做,活学活用,才是我们学习设计模式的目的。