HTML5技术

设计模式(1)单例模式(Singleton) - Fonour

字号+ 作者:H5之家 来源:H5之家 2017-04-23 12:00 我要评论( )

设计模式(0)简单工厂模式 源码地址 0 单例模式简介0.0 单例模式定义 单例模式是GOF二十三中经典设计模式的简单常用的一种设计模式,单例模式的基本结构需满足以下要求。 单例模式的核心结构只有一个单例类,单例模式要保证这个类在运行期间只能被实例化一

设计模式(0)简单工厂模式

源码地址

0 单例模式简介 0.0 单例模式定义

单例模式是GOF二十三中经典设计模式的简单常用的一种设计模式,单例模式的基本结构需满足以下要求。

  • 单例模式的核心结构只有一个单例类,单例模式要保证这个类在运行期间只能被实例化一次,即只会被创建唯一的一个单例类的实例。
  • 单例模式需要提供一个全局唯一能得到这个类实例的访问点,一般通过定义一个名称类似为GetInstance的公用方法实现这一目的。
  • 要满足上面的两点要求,应该很容易的想到:

    1.该类的构造函数应该是私有的,不能随意被实例化是保证只有一个实例的前提。

    2.该类需提供一个公开的且返回值类型为单例类类型的公用方法。

    来看一下单例模式的基本结构图:

    1

    0.1 单例模式应用场景

    通过上面对单例模式基本定义的了解,单例模式的应用场景也就很明确了。

    单例模式适用于各种系统中某个类的对象只能存在一个类似场景, 我们现在回顾一下上一篇简单工厂模式中的大致实现

    简单工厂类 Factory { 创建英雄的静态方法 IHero CreateHero(string heroName) { switch (heroName) { : return new DH(); : return new WD(); : return new KOG(); : return new POM(); default: return null; } } }

    恶魔猎手 DH : IHero { 秀出自己的技能 ShowSkills() { Console.WriteLine(); } }

    通过简单工厂模式确实达到了接口隔离的目的,外部使用无需关注内部类的具体实现工程,只通过简单工厂类创建想要的对象即可,但这里有一个致命的问题就是,我们玩儿游戏的过程中,英雄会存在一个死亡和复活的场景,我们简单的把英雄祭坛理解为创建英雄的简单工厂,假设当我们复活英雄的时候,是通过工厂类创建英雄的一个过程,那么我们面临的问题就出现了,我本来一个6级的大恶魔猎手,由于走位过度风骚,走进了祭坛,现在在通过工厂创建的时候,由于是又重新new了一个对象,从祭坛中走出了一个萌叉叉的1级小恶魔猎手……

    为保证我的那个6级大恶魔还是那个6级大恶魔,一身装备一个不少的走出祭坛,至此也就到了必须引入单例模式的时候了。

    1 单例模式详解 1.0单例模式的基本实现-懒汉式单例模式

    按照单例模式的2个基本特征:私有的构造函数和公开的GetInstance方法。将DH类进行如下改造,代码的具体意图已经通过注释详细解释。

    恶魔猎手 DH : IHero { DH dh; 私有的构造函数,能够保证该类不会在外部被随意实例化,是保证该类只用一个实例的基本前提 DH() { } 定义一个静态的公开的GetInstance方法供外部得到DH类唯一实例是调用 DH GetInstance() { //先判断dh是否已经被实例化,若未被实例化,先实例化得到DH类的实例 (dh == null) { dh = new DH(); } return dh; } 秀出自己的技能 ShowSkills() { Console.WriteLine(); } }

    修改Factory简单工厂类中创建DH实例部分的代码

    简单工厂类 Factory { 创建英雄的静态方法 IHero CreateHero(string heroName) { switch (heroName) { : : return new WD(); : return new KOG(); : return new POM(); default: return null; } } }

    客户端测试

    static void Main(string[] args) { IHero dh1 = Factory.CreateHero(); IHero dh2 = Factory.CreateHero(); if (dh1.Equals(dh2)) Console.WriteLine(); else Console.WriteLine(); IHero wd1 = Factory.CreateHero(); IHero wd2 = Factory.CreateHero(); if (wd1.Equals(wd1)) Console.WriteLine(); else Console.WriteLine(); Console.ReadLine(); }

    输出结果如下

    至此我们对DH这个类应用了单例模式来确保无论何时走出祭坛的都是同一个DH对象,从DH对象被实例化的实际来看,是在被使用的时候才会被创建,这种方式被成为懒汉式单例模式

    有一天突发奇想,我建造两个英雄祭坛(两个简单工厂类),用我APM500+的超快手速,同时在两个祭坛里生产同一个英雄,发现我拥有了2个6级大恶魔……(当然了,实际中不会有这个bug存在)

    这就是基本懒汉式单例模式要面对的多线程问题,也就是说基本懒汉式单例模式的写法是无法做到线程级别安全的。

    问题的关键就在获取DH类实例的GetInstance方法的内部实现中

    if (dh == null) { dh = new DH(); } return dh;

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • 设计模式(0)简单工厂模式 - Fonour

      设计模式(0)简单工厂模式 - Fonour

      2017-03-25 15:01

    • 蟠桃果园系统模式开发 - linoin

      蟠桃果园系统模式开发 - linoin

      2017-03-06 16:00

    • CSS Float 以及相关布局模式 - 刘江龙

      CSS Float 以及相关布局模式 - 刘江龙

      2016-11-03 10:00

    • Socket编程模式理解与对比 - liyux

      Socket编程模式理解与对比 - liyux

      2016-06-30 16:09

    网友点评
    k