zoukankan      html  css  js  c++  java
  • 设计模式之单例模式(一) zkh

    设计模式之单例模式(创建型设计模式)

    先说一段废话记录一下生活吧

      又是一年毕业季,临近毕业,最近当然是在忙毕业设计了,今天查重报告下来了,查重率百分之二十八点多,要求百分之二十,真他妈shit了,加上天气炎热,最近很是烦躁,心情像一坨屎,每天上午死在宿舍,下午去篮球场,不过还有nba可以看,最近几场东西部决赛看的真是心脏不太好,昨天骑士和凯子抢七,老詹是真牛批,一个人扛着一个队硬是拿下了比赛,今天火箭和勇士抢七,本来想看我火在主场将西部决赛冠军收入囊中,但是没有保罗的火箭就是不太稳啊,喜欢登哥但是有时候总是掉链子,尤其今天的火箭27中0,我他么更是shit了.怎么说呢,明年接着来吧.

      最近不知道看些什么,写些什么,还是写写设计模式吧,之前看过一些设计模式,没有记录下来,这次写一下整理整理吧.

    ========================================================================

    单例模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

    简单来说,我的对象由我自己来创建(单例当然只创建一个对象了),但是我可以给你们使用.

    注意:

    • 1、单例类只能有一个实例。
    • 2、单例类必须自己创建自己的唯一实例。
    • 3、单例类必须给所有其他对象提供这一实例。

    主要解决:一个全局使用的类频繁地创建与销毁。

    何时使用:当您想控制实例数目,节省系统资源的时候。

    优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如首页页面缓存)。

                2、避免对资源的多重占用(比如写文件操作)。

    缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

    使用场景: 1、要求生产唯一序列号。

          2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。

          3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

    然后我们来看一下单例模式的类图,如下图所示:

    简单的说一下吧:

    1.首先我们要有一个私有的构造方法,这样就能满足这个对象只能由我们自己创建的这个条件了

    2.然后呢,我们提供一个私有的变量,用来存放这个唯一的实例

    3.提供一个方法,返回这个唯一的实例(当然我们要进行一下判断了)

    接下来我们可以简单的写一个单例类

    namespace Singleton
    {
        /// <summary>
        /// 这是单例类
        /// </summary>
        public class Unique
        {
            //提供一个变量来存储唯一的实例
            private static  Unique uniqueInstance;
            //提供一个私有的构造器
            private  Unique() { }
            //提供一个方法供其他类进行调用
            public static Unique GetUniqueInstance() {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton.Unique();
                }
                return uniqueInstance;
            }
            public void Show() {
                Console.WriteLine("单例中的方法");
            }
        }
    }
    单例类
    namespace Singleton
    {
        class Program
        {
            static void Main(string[] args)
            {
                Unique unique = Unique.GetUniqueInstance();
                unique.Show();
                Console.ReadKey();
            }
        }
    }
    主程序

      写到这,是不是觉得很简单呢,当然了,因为我们是单线程的程序,所以不会出现问题.

      那我们考虑一下多线程的情况,假如现在有两个线程,其中一个线程执行到了GetUniqueInstance()方法,判断等于空,接着会去创建单例对象,这时第二个线程也来了,同样也执行到了GetUniqueInstance().但是呢,这时第一个线程还没有将对象创建出来(new一个对象哪有那么容易,当然是需要时间的了,就像你找女朋友一样),所以判断也为空,接着也去创建这个单例对象,这种情况是不是就创建了两个单例对象呢,这当然是错的,违背了我们只创建一个对象的初衷,所以我们要解决多线程的问题.

    ================================以下多线程=========================================

      菜鸟教程上介绍了6种创建单例模式的方式,其中一种是不能保证线程安全的,也就是和我们上边写的类似,其余5种分别是:1 懒汉式线程安全,2 饿汉式,3 双检锁/双重校验锁,4 登记式/静态内部类,5 枚举

    下面我先简单介绍一下饿汉式

    饿汉式,就是一个饥饿的汉子(此处一个猥琐的表情),也就是在单例类内部的变量直接去把对象创建出来,而不是在GetUniqueInstance()中给这个变量赋值,(这个过程实在java类加载时初始化,对应的.net是哪个步骤我还不太清除,希望大神看到这能够指点迷津,给我留言哦)是CLR吗,底层我还没研究过...

    下面我们来改造一下

     public class Unique
        {
            //提供一个变量来存储唯一的实例
            private static Unique uniqueInstance = new Unique ();
            //提供一个私有的构造器
            private Unique() { }
            //提供一个方法供其他类进行调用
            public static Unique GetUniqueInstance()
            {
                return uniqueInstance;
            }
            public void Show()
            {
                Console.WriteLine("单例中的方法");
            }
        }
    单例类

    这就改造好了,很简单的,尝试一下

     接着看一下双检锁/双重校验锁吧

    //双层判断 中间加锁
        public class Unique
        {
            //提供一个变量来存储唯一的实例
            private static Unique uniqueInstance;
            //标识对象 可以锁这个对象
            private static readonly object obj = new object();
            //提供一个私有的构造器
            private Unique() { }
            //提供一个方法供其他类进行调用
            public static Unique GetUniqueInstance()
            {
                if (uniqueInstance == null) { //没有这层判断也可以,但是每次都是先锁对象,再去判断,加锁解锁耗时间,所以有这层判断更好
                    lock (obj) {
                        if (uniqueInstance == null) {
                            uniqueInstance = new Unique();
                        }
                    }
                }
                return uniqueInstance;
            }
            public void Show()
            {
                Console.WriteLine("单例中的方法");
            }
        }
    单例类

    之前一直认为这个双重锁就是懒汉模式,因为他比较懒,使用的时候才去创建,java中的懒汉模式使用到了synchronized关键字,也就是同步方法.C#中同步方法我还没想起来是哪个关键字,唉,才疏学浅,菜的一批,大家就自行百度吧

     写到这也差不多了,剩下还有几种就不写了,有点饿,该去吃晚饭了

    当然了,最后一句,欢迎指正,欢迎留言,欢迎转载(转载最好把我的博客地址贴上)

  • 相关阅读:
    013.[转] 云原生
    012.[转] 云计算
    011.maven 继承与聚合
    Window常用且通用快捷键
    Hibernate Validator Engine的用法
    Mybatis书写
    Ajax错误
    apache commons lang架包介绍
    Mybatis使用Mybatis-generator插件及配置(数据库逆向工程)
    二分搜索树
  • 原文地址:https://www.cnblogs.com/zkhbalance/p/9106965.html
Copyright © 2011-2022 走看看