您好,欢迎访问三七文档
单例模式动机•在软件系统中,经常有这样一些特殊类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。•保证一个实例应该是类设计者(类本身)的责任,而不是使用者(客户终端)的责任。类也需要计划生育•“大鸟,今天我在公司写了一个MDI窗体程序,当中有一个是'工具'箱窗体,问题就是,我希望工具箱要么不出现,要么只出现一个,可实际上却是我每点击菜单,实例化‘工具箱’,它就会出来一个,这样点击多次就会出现多个‘工具箱’,怎么办?”•显然这个工具箱需要计划生育,它超生了。publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidForm1_Load(objectsender,EventArgse){this.IsMdiContainer=true;}privatevoidToolStripMenuItemToolbox_Click(objectsender,EventArgse){FormToolboxftb=newFormToolbox();ftb.MdiParent=this;ftb.Show();}}表示它是多文档界面MID子窗体的容器(父窗体)工具箱启动代码,实例化FormToolbox,并设置其父窗体为当前窗体Form1判断对象ftb是否是nullprivateFormToolboxftb;privatevoidToolStripMenuItemToolbox_Click(objectsender,EventArgse){if(ftb==null){ftb=newFormToolbox();ftb.MdiParent=this;ftb.Show();}}判断是否实例化如果现在不但要在菜单里启动‘工具箱’,还需要在‘工具栏’上一个按钮来启动‘工具箱’,该如何做?•首先加一个工具栏控件toolStrip,然后再在按钮toolStripButton1的click试卷代码里添加相同代码即可。privateFormToolboxftb;privatevoidtoolStripButton1_Click(objectsender,EventArgse){if(ftb==null){ftb=newFormToolbox();ftb.MdiParent=this;ftb.Show();}}分析•复制黏贴是最容易的编程,也是最没有价值的编程。现在两个地方代码复制在一起,就是重复。要是需求变化或者有Bug时就需要改多个地方。•把程序运行后,启动“工具箱”,然后把“工具箱”关闭,再点启动按钮试试?关闭后实例并没有变为NULL,而是Disposedif(ftb==null||ftb.IsDisposed)privateFormToolboxftb;privatevoidToolStripMenuItemToolbox_Click(objectsender,EventArgse){openToolbox();}privatevoidtoolStripButton1_Click(objectsender,EventArgse){openToolbox();}privatevoidopenToolbox(){if(ftb==null||ftb.IsDisposed){ftb=newFormToolbox();ftb.MdiParent=this;ftb.Show();}}提炼出“打开工具箱”的方法夫妻生小孩,第二胎由谁来负责?老板问下属,报告交了没有,下属可能说“早交了”,也可能说“还差一点内容,还没交”,到底交没交,只有下属知道。工具箱FormToolbox是否实例化都在MID主窗体Form1的代码里判断。工具箱From1里应该只是通知启动“工具箱”,至于“工具箱”窗体是否实例化过,应该由“工具箱”自己判断。是否实例化是工具箱自己的判断责任。publicpartialclass:Form{privateFormToolboxftb=null;FormToolbox(){InitializeComponent();}publicGetInstance(){if(ftb==null||ftb.IsDisposed){ftb=newFormToolbox();ftb.MdiParent=Form1.ActiveForm;}returnftb;}}声明一个静态类变量工具箱窗体自己判断构造函数私有化,外部代码不能直接new来实例化它全局访问点。工具箱的实例化方法,返回一个实例化的本工具箱对象,注意是静态的。实例化的对象存在静态变量ftb中,以后就可以不用实例而得到它publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidForm1_Load(objectsender,EventArgse){this.IsMdiContainer=true;}privatevoidToolStripMenuItemToolbox_Click(objectsender,EventArgse){FormToolbox.GetInstance().Show();}privatevoidtoolStripButton1_Click(objectsender,EventArgse){FormToolbox.GetInstance().Show();}}这样一来,Form1不用考虑是否要去实例化的问题,把责任都归给应该负责的类去处理。单例模式•单例模式确保某一个类只有一个实例,而且自行实例化(自己保存它的唯一实例),并提供一个访问它的全局访问点。通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象,一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。单例模式•显然单例模式的要点有三个:•一是某个类只能有一个实例(本身的初始方法为private,且只有实例为空的时候才建立)•二是它必须自行创建这个实例(作为一个成员方法,返回)•三是它必须自行向整个系统提供这个实例(返回的对象也是static)单例模式基本代码classSingleton{Singletoninstance;Singleton(){}publicGetInstance(){if(instance==null){instance=newSingleton();}returninstance;}}构造函数私有化,堵死外界利用new来创建此类实例的可能本类实例唯一全局访问点,返回唯一攒在的实例对象若实例存在,返回已有实例,若不存在,则创建一个新实例,确保实例只有一个。staticvoidMain(string[]args){Singletons1=Singleton.GetInstance();Singletons2=Singleton.GetInstance();if(s1==s2){Console.WriteLine(Objectsarethesameinstance);}Console.Read();}
本文标题:12-单例模式课件
链接地址:https://www.777doc.com/doc-3626115 .html