C#设计模式笔记(1)

来源:互联网 发布:win10 sql sever 编辑:程序博客网 时间:2024/05/21 17:07

设计模式

我主要侧重理解,毕竟经验太少,而又需要理解。所以这篇博文仅作为自己消化已有的知识用。

单例模式

单例模式,从字面上理解就是这个类我要一个而且也只允许一个产生。这是我一开始的理解。那么我在学习面向对象的过程中,知道的产生类的方式为:类名 实例引用名称=new 类名(参数);

那么,现在问题来了,既然要全局都只允许有且只有一个类的实例,怎么办呢?没有任何专业知识的前提下,我们都知道“节流”。就是不要让这个类“随意”产生实例。而这个想法的技术实现是怎样的呢?我们不妨慢慢来。

先看一下类是怎么生成实例的(我目前基础差,必须这么干。。。。。。)。使用类类型生成该类的实例其实就是一句话:使用new关键字来分配对象【1】。那么,深入一点new关键字是怎么进行类的实例的产生的?使用new关键字后,首先分配内存,然后调用类的构造函数进行实例的初始化。也就是说,创建类的根本操作是调用了类的构造函数。所以说,防止利用new生成类的实例就是防止类的构造函数被调用。

class ExampleClass{    private ExampleClass()    {    /*构造函数的内容*/    }}

那么,紧接着就会有另外一个问题:连构造函数都被干掉了(不能通过new自动调用),那我们怎么生成这个类的实例(毕竟我们讨论的是单例,还得有一个实例,否则这个类不就没用了么。。。。)呢?

这个时候,我们可以使用静态方法。为什么是静态?因为在生成这个类之前,这个类只有定义没有实例,只能用静态方法跟类中的内容进行“联通”。而有了这个联通的桥梁,我们也就可以在new不能访问构造函数的前提下,访问到private的构造函数。原因是,静态函数把执行上下文(自己的理解,也许不对。意会)带入到了类内(或者说是定义范围内,我不是很清楚。。。),而这个时候,构造函数的private对内部已经不管用了(嘿嘿,机智啊),这个时候就可以使用(私有)构造函数了(同样是通过new关键字)。这个时候代码大概是这样的

class ExampleClass{    private ExampleClass()    {    /*构造函数的内容*/    }    public static CreateInstance()    {      ExampleClass instanceRef = new ExampleClass();     /*剩下的操作*/      }}

但是,这个时候又跳出来一个问题:上述代码中通过public的静态函数“解锁”了私有构造函数,那么不就又等于构造函数可以任意使用了吗(可以随意的new然后返回该实例的引用)?解决这个问题的思路其实很简单,就是设定一个等效的flag位,用来指示到底这个类有没有被创建过。这里使用指向该类的引用类型变量,如果这个变量为null,说明这个类从来没有实例被创建过;反之,就代表已经创建过实例,不应该再执行new ExampleClass()了。此时,代码如下

class ExampleClass{    /*增加的标志位*/    private static ExampleClass uniqueRef;    private ExampleClass()    {    /*构造函数的内容*/    }    public static ExampleClass CreateInstance()    {      if( uniqueRef == null )      {          /*说明并没有生成过类的实例*/          ExampleClass instanceRef = new ExampleClass();      }     /*剩下的操作*/       return uniqueRef;   }}

我自己在反复看这个代码的时候有个问题:为什么标志位uniqueRef要为private和static的?我的理解为:static有两种解释:首先如果不是static的话,根本就无法在静态方法CreateInstance()中赋值,其次在道理上也确实应该是static的,因为这个实例是这个类的唯一实例(这个实例的引用是伴随类的);private其实可以为public,不过这时候这个变量会有两种可能:空和非空。不过如果这样,在使用的时候需要判断,增加了不必要的书写麻烦。而将这个访问属性改为private后,将这个判断放在CreateInstance()中则使整体代码更加简洁。

最后,注意这个代码是线程不安全的,但是多线程的知识我还不会,慢慢积累吧。。。

0 0
原创粉丝点击