【机房合作】单例模式的实现(一)

         重构的时候,没有使用单例,合作的时候就必须要实现一下了,虽然单例模式感觉很简单,但是需要注意的点也非常的多。下边先总结一个单例模式是什么


单例模式定义


保证一个类仅有一个实例,并提供一个访问他的全局访问点。


自己的理解:单例模式的中心思想就是一个类只能有一个实例,外界可以访问这个类的实例,但却不能实例化类的其他实例,如何实现不让类被实例化呢?我们来看看单例的UML吧


UML结构图




从图中我们可以得到几点讯息:1.类中有一个私有的构造函数,这样外界就不能利用New来创建此类的实例   2.类向外界提供了一个公共的静态的方法(GetInstance),这就是类向外界提供的全局访问点,外界只能通过这个方法来获得类的唯一实例,而且这个方法也保证了该类只有一个实例。


下边我们看看代码是如何实现的:

    public class Singleton
    {
        private static Singleton instance;

        //私有的构造函数
        private Singleton()
        {

        }

        //全局访问点,防止了该类只有一个实例
        public static Singleton GetInstance()
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }


       记得原来师姐提过一个问题,就是GetInstance的方法已经是public的了,为什么一定要是静态的?当时听到这个问题,懵逼了。为什么会懵呢,我也好好的自省了一下,就是两点:1.脑子的里的东西少,想要去深究,也深究不出来什么原委  2.懒得动手去帮助自己思考,其实这个问题你只要把static去掉,看他报什么错就好了。但就是懒得去做,这是我需要加强的方面。

      回到这个问题,其实非常简单,如果不是静态的方法,你需要实例化这个类,才可以使用这个方法。但是我们构造函数用的是私有的,也就是外界不可能new出一个实例,只能通过这个方法入口来获得该类的实例,所以必须要加static,给外界提供一个全局的方法。


合作时遇到的问题:


我们在窗体上使用了panel控件,如果再加载出来一个窗体,我们就会出现父窗体子窗体的遮挡问题,开始我们才用了设置句柄的方法,

 

客户端代码如下:

  private void mnsModifyPWD_Click(object sender, EventArgs e)
        {


            frmModifyPWD s1 = frmModifyPWD.GetInstance();
            s1.MdiParent = this;
            s1.Show();

            SetParent((int)s1.Handle, (int)this.panel1.Handle);
            
            
        }


frmModifyPWD代码:

<span style="white-space:pre">	</span>private frmModifyPWD()
        {
            InitializeComponent();
        }

        private static frmModifyPWD si;

        public static frmModifyPWD GetInstance()
        {
            if (si == null)
            {
                si = new frmModifyPWD();
            }
            return si;
        }

这样会出现一个问题,就是当我们第一次打开这个窗体的时候可以实现单例模式,但是当把这个窗体关闭了之后,就再也打不开了,这是因为当我们把子窗体关闭的时候,资源就被释放了,但是这个类的实例不是为null的,当我们需要他再次show的时候,就会报出下边这个错误




       也就是说我们要使用这个实例,但是他内部的资源已经被释放了,我们又不可以在重新实例化出来一个新的,所以说这个方法存在一点点问题,只要改一个地方,就可以实现了,那就是在GetInstance方法中的if判断中加一个条件,如果实例为空或者实例已经被释放,那么就重新实例化出来一个新的,


代码如下:





总结

       其实单例虽然看似简单,其实需要注意的细节点特别的多,但凡一个点没有注意到,就有可能导致失败,下一篇总结多线程时的单例+panel遮挡问题的另外一种解决方法






评论 97
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值