C#设计模式之单例模式实例讲解

 更新时间:2014年10月25日 10:44:03   投稿:junjie  
这篇文章主要介绍了C#设计模式之单例模式实例讲解,本文讲解了单例模式的定义、单例模式的优缺点,需要的朋友可以参考下

前言

最近开始花点心思研究下设计模式,主要还是让自己写的代码可重用性高、保证代码可靠性。所谓设计模式,我找了下定义:是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。

为什么要提倡“Design Pattern(设计模式)”?

根本原因是为了代码复用,增加可维护性。因此这次我们来学习下设计模式,最后会通过C#语言来实现这些设计模式作为例子,深刻理解其中的精髓。

定义

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

特点

1、 某个类只能有一个实例
2、它必须自行创建这个实例
3、它必须自行向整个系统提供这个实例。

优缺点

优点:

一、实例控制

单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。

二、灵活性

因为类控制了实例化过程,所以类可以灵活更改实例化过程。

缺点:

一、开销

虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。

二、可能的开发混淆

使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。

三、对象生存期

不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。

复制代码 代码如下:

/// <summary>
    /// 单例模式
    /// </summary>
    public class Singleton
    {
        // 定义一个静态变量来保存类的实例
        private static Singleton mySingleton;

        // 定义私有构造函数,使外界不能创建该类实例
        private Singleton()
        {
        }

        //定义公有方法提供一个全局访问点。
        public static Singleton GetInstance()
        {
            //这里的lock其实使用的原理可以用一个词语来概括“互斥”这个概念也是操作系统的精髓
            //其实就是当一个进程进来访问的时候,其他进程便先挂起状态
            if (mySingleton == null)
            {
                mySingleton = new Singleton();
            }
            return mySingleton;
        }
    }

上面的单例模式的实现是有问题的,当多个用户或者方法同时访问的时候,便会出现多个用户同时拿到了mySingleton==null的结果,这个明显不是我们想要的,因此,我们应该通过一个锁来互斥这个方法,当很多线程同时访问的时候,只允许一个线程进入到代码中执行,而其他的便只能处于挂起的状态。

复制代码 代码如下:

/// <summary>
    /// 单例模式
    /// </summary>
    public class Singleton
    {
        // 定义一个静态变量来保存类的实例
        private static Singleton mySingleton;

        // 定义一个标识确保线程同步
        private static readonly object locker = new object();


        // 定义私有构造函数,使外界不能创建该类实例
        private Singleton()
        {
        }

        //定义公有方法提供一个全局访问点。
        public static Singleton GetInstance()
        {
            //这里的lock其实使用的原理可以用一个词语来概括“互斥”这个概念也是操作系统的精髓
            //其实就是当一个进程进来访问的时候,其他进程便先挂起状态
            if (mySingleton == null)//区别就在这里
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建,否则直接返回
                    if (mySingleton == null)
                    {
                        mySingleton = new Singleton();
                    }
                }
            }
            return mySingleton;
        }
    }

其实在一些项目中,单例模式早就有了体现。在开发asp.net的项目中,就已经用这种方法来包装http上下文来实现计算机资源的节省。

复制代码 代码如下:

/// <summary>
        /// 业务仓储
        /// </summary>
        public IBLL.IBLLSession BLLSession;

        //---------------------定义上下文属性
        #region 实例构造函数 初始化业务仓储 + OperateContext()
        public OperateContext()
        {
            BLLSession = DI.SpringHelper.GetObject<IBLL.IBLLSession>("BLLSession");
        }
        #endregion

        #region Http上下文 以及相关属性
        /// <summary>
        /// Http上下文
        /// </summary>
        HttpContext ContextHttp
        {
            get
            {
                return HttpContext.Current;
            }
        }

        HttpResponse Response
        {
            get
            {
                return ContextHttp.Response;
            }
        }
        HttpRequest Request
        {
            get
            {
                return ContextHttp.Request;
            }
        }
        HttpSessionState Session
        {
            get
            {
                return ContextHttp.Session;
            }
        }
        #endregion

        #region 获取当前操作上下文(存在线程中,提高效率) + OperateContext Current
        // <summary>
        /// 获取当前操作上下文(存在线程中,提高效率)
        /// </summary>
        public static OperateContext Current
        {
            get
            {
                OperateContext o = CallContext.GetData(typeof(OperateContext).Name) as OperateContext;
                if (o == null)
                {
                    o = new OperateContext();
                    CallContext.SetData(typeof(OperateContext).Name, o);
                }
                return o;
            }
        }
        #endregion

总结

到这里,就和大家一起先了解了单例模式到底是个什么东西,其实在一些项目中,这种模式就已经应用了,只是我们没有去发现和总结,不过本来设计模式就是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。哎。。。。这次是第二次编辑了,本来这个单例模式已经发布了好多天,竟然被我新的一篇观察者模式给覆盖了,数据取不回来,只能匆匆完稿,大家见谅啊,有问题我们一起来讨论,毕竟我也是初学者。

相关文章

  • 一文搞懂c# await,async执行流

    一文搞懂c# await,async执行流

    这篇文章主要介绍了c# await,async执行流的相关知识,文章讲解的非常细致,代码帮助理解和学习,感兴趣的朋友可以了解下
    2020-06-06
  • C# winform分页查询的实现示例

    C# winform分页查询的实现示例

    这篇文章主要介绍了C# winform分页查询的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 当用户退出点击浏览器后退仍可回到原来页面的解决方案

    当用户退出点击浏览器后退仍可回到原来页面的解决方案

    这篇文章主要介绍了当用户退出点击浏览器后退仍可回到原来页面的解决方案 的相关资料,需要的朋友可以参考下
    2016-03-03
  • C#与js实现去除textbox文本框里面重复记录的方法

    C#与js实现去除textbox文本框里面重复记录的方法

    这篇文章主要介绍了C#与js实现去除textbox文本框里面重复记录的方法,很实用的功能,需要的朋友可以参考下
    2014-08-08
  • C#使用NPOI导出Excel类封装

    C#使用NPOI导出Excel类封装

    这篇文章主要为大家详细介绍了C#使用NPOI导出Excel类封装,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • C#异步编程之async/await详解

    C#异步编程之async/await详解

    异步这个概念在不同语境下有不同的解释,不同的编程语言有不同异步编程方法,在C#语言中,常常使用async/await等关键字,和Task等类来实现异步编程。本文就来和大家聊聊async与await吧
    2023-03-03
  • C#多线程系列之原子操作

    C#多线程系列之原子操作

    本文详细讲解了C#多线程的原子操作,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • c# 解决IIS写Excel的权限问题

    c# 解决IIS写Excel的权限问题

    使用以上方法必须对dcom进行配置,给用户使用office的权限
    2012-10-10
  • C# 汉字与拼音互转的实现示例

    C# 汉字与拼音互转的实现示例

    本文主要介绍了C# 汉字与拼音互转的实现示例,文中根据实例编码详细介绍的十分详尽,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • c#构造初始化的顺序浅析

    c#构造初始化的顺序浅析

    这篇文章介绍了c#构造初始化的顺序,有需要的朋友可以参考一下
    2013-08-08

最新评论