C#机房重构——单例模式

前言

        在机房重构之前,我们学习了设计模式,在这次重构中,我们的任务就是将这些模式,添加到机房的重构中去。现在先来解决一个最简单的问题——窗体的超生。

        如果不加以限制,结果会是这样:

C#机房重构——单例模式_第1张图片

        非常的不友好。那么我们如何来解决这个问题呢?——单例模式。

单例模式

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

使用方法

        在这里有两种理解。一种正确的一种错误的。

第一种

        首先把声明放到类的全局变量中,然后写一个判断是否实例化过的方法,当需要该窗体显示时,调用该方法。代码如下:(注册)

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;
    }
}
    
        这样,我们在客户端调用时,只需要写:frmRegister.GetInstance().Show();就可以了,客户端不用做任何工作,只是在需要的时候调用一下方法就可以了。而且外部不能通过new来实例化这个窗体,因为这个窗体只有一个实例化,被这个类自己保存着。调用方法时类会判断有没有被实例化过,如果没有,则实例化一个返回,如果有,则直接返回。

机房中的单例模式

       虽然第一种方法不符合面向对象,但是我为什么要写它呢?这就和我的机房有点关系。大家都知道,机房收费系统的主界面有一张图片,这就需要一个转换容器的api函数去做相应的转换,这样一来,单例模式在实际中的应用就要多点东西,也就是在每一个子窗体上都加上引用,然后在每个窗体中去做调换,我认为这是相当麻烦并且也不是一个好办法,所以,在反复比较下,我选择了之前相对错误的做法,将判断的权利交给主窗体。

总结

        一个模式的应用并不是死板的,在对的时候用对的模式,不拘泥于模式的格式,怎样使系统做起来更简单,更好用,就怎样做,活学活用,才是我们学习设计模式的目的。



你可能感兴趣的:(单例模式,机房收费系统重构)