单例模式理解 (2012/7/18)
单例模式(singleton),保证一个类仅有一个实例,并提供一个访问他的全局的访问点。
在看单例模式中,大话中首先举出了一个例子,通过按钮触发的事件来判断是否为null,程杰老师提出from1只是启动“工具箱”,而“工具箱”窗体是否被实例化过,应该是由工具箱自己决定的。
看到这里让我想到了一个很经典的故事。
有一位禅师很喜欢养兰花. 有一次他外出云游,就把兰花交代给徒弟照料.徒弟知道这是师傅的爱物,于是也小心照顾,兰花一直生长的很好.也是就在禅师回来的前一天,他不小心把兰花摔到地上,兰花坏了.徒弟非常担心,他自己受罚倒不要紧,他害怕师傅会生气伤心. 问问自己,如果你是师傅,你会怎样处理?禅师回来以后知道了,并没有生气,也没有惩罚. 他告诉徒弟:
"我当初种兰花,不是为了今天生气来的。
《拆掉思维的墙》一书中告诉我们自己是自己的掌控者,快乐,悲伤,是自己掌控的,不是由他人来掌控的。这个世界上有一小部分人,他们有一个奇妙的心智转化器,他们好像没有痛苦按钮,只有快乐按钮,并且按钮就在自己手上. 我们的心智模式是由我们自己来选择的,而我们程序中的模式是由我们程序员来决定的,再微观到我们编程中,类是否被实例化过,应该是由它自己来判断。
开始我们把实例化的判断放在了其他的按钮事件中。
//类声明变量。 Private FormToolbox ftb; Private void ToolStripMenuItemToolbox_Click(object sender,Eventargs e) { //判断是否实例化过,如果为null说明没有实例化过。 if (ftb==null) { ftb=new FormToolBox(); ftb.MdiParent=this; ftb.Show(); } }
这就相当于生活中受害者模式,是由外界触发。
Private victim lisi ; Private void Ohters_Click(object one ,EventArgs c) { if(bad things) { complain and complain and complain ……. } else { be free .be happy; } }
而生活中掌控者心智模式才是强者啊。
Public partial class commander:commanderModel { private static commander lisi=null; private commander() { My Heart Will Go On; } public static lisi myselfControl() { if (bad thing) { I Believe the sunshine always after the rain } else { I am a Big Girl , haha . } } }
计算机世界的单例模式。
单例模式的图。
从受害者模式变成掌控者模式,编程中的单例模式,判断一个对象是否是null,不是靠的其他的对象,而是靠自己判断。从开始的需要其他按钮触发来判断是否实例化到,改动自己类的构造方法。类的每个实例化的对象都会系统都会默认生成空的构造方法,若有显示定义的构造方法,默认的构造方法就会消失了,我们就是从这这下手。
通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你创建,并且它可以提供一个实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以;保证没有其他实例可以被访问该实例的方法。
Public partial class FormToolbox:Form { //声明一个静态变量类。 private static FormToolbox ftb=null; //构造方法私有,外部代码不能通过直接new来访问它。 private FormToolbox() { InitializeComponent(); } //得到类实例的方法,返回值就是类本身对象,注意也是静态的。 public static FormToolbox GetInstance() { //当内部的变量是ftb或是null或者被dispose过,则new它。并且设计MdiParent为Form1,此时将实例化的对象存在静态变量ftb中,以后就可以不用实例化而得到它了。 if (ftb==null || ftb.IsDisposed) { ftb=new FormToolbox(); ftb.MdiParent=Form1.ActiveForm } } }
多线程的单例。
在这里简单的提一下,我们考虑到多个线程同时访问时,调用的GetInstance(),会有可能创建多个实例,针对这样的问题,大话中提出了‘饿汉式单例模式”和“懒汉式单例模式”是解决多线程创建实例的问题,给心加了一把锁,而the
key to the heart是自己。‘单锁定’是这个对象是不可以碰触的,一碰触这个线程便lock了。‘双重锁定’是在实例未被创建时就加的锁,lock机制,这两个进程一个进入一个在外面等候,双重锁定一个进程进入后直到另一个进程出来后才能创建实例。可以用反证法证明如果有在lock里面不加上实例是否为null的判断。而饿汉式和懒汉式的区别,就知道自己饿的时候,就啥也不想啥都吃了,懒的时候,最近减肥可能就不吃了呢。理解了一下,饿汉式是用不用只要程序运行就创建了,懒汉式是使用时创建吧(简单理解)。
简单理解,具体的以后用到再议,请继续关注哈。(在合作开发中组长要求用的是最基本的单例模式,用到以后再论。)
以上比喻也只是从单例模式片面的角度来说,请多多谅解和指教!