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#使用WinRar命令进行压缩和解压缩操作的实现方法

    C#使用WinRar命令进行压缩和解压缩操作的实现方法

    这篇文章主要介绍了C#使用WinRar命令进行压缩和解压缩操作的实现方法,涉及C#基于Process类操作WinRar命令的相关实现技巧,代码简洁实用,需要的朋友可以参考下
    2016-06-06
  • c#实现无标题栏窗口的拖动

    c#实现无标题栏窗口的拖动

    本篇文章是对c#中实现无标题栏窗口拖动的方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • WPF MVVM示例讲解

    WPF MVVM示例讲解

    WPF技术的主要特点是数据驱动UI,所以在使用WPF技术开发的过程中是以数据为核心的,WPF提供了数据绑定机制,当数据发生变化时,WPF会自动发出通知去更新UI,这篇文章通过示例让大家体验下WPF MVM,有需要的朋友可以参考下
    2015-08-08
  • C#实现在控制台输出当前系统时间的方法

    C#实现在控制台输出当前系统时间的方法

    这篇文章主要介绍了C#实现在控制台输出当前系统时间的方法,涉及C#时间函数DateTime.Now的使用方法,需要的朋友可以参考下
    2015-04-04
  • WinForm实现为ComboBox绑定数据源并提供下拉提示功能

    WinForm实现为ComboBox绑定数据源并提供下拉提示功能

    这篇文章主要介绍了WinForm实现为ComboBox绑定数据源并提供下拉提示功能,是非常实用的功能,需要的朋友可以参考下
    2014-08-08
  • C#实现电脑麦克风录音

    C#实现电脑麦克风录音

    这篇文章主要为大家详细介绍了C#实现电脑麦克风录音,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • 详解C#扩展方法原理及其使用

    详解C#扩展方法原理及其使用

    这篇文章主要介绍了C#扩展方法原理及其使用的的相关资料,文中代码非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06
  • C#语言async await之迭代器工作原理示例解析

    C#语言async await之迭代器工作原理示例解析

    这篇文章主要为大家介绍了C#语言async await之迭代器工作原理示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • C# 实现与现有.NET事件桥接简单实例

    C# 实现与现有.NET事件桥接简单实例

    这篇文章主要介绍了C# 实现与现有.NET事件桥接简单实例的相关资料,需要的朋友可以参考下
    2017-03-03
  • AnyChat的视频会议程序实例详解

    AnyChat的视频会议程序实例详解

    AnyChat是一款跨平台的音视频解决方案。通过本篇文章给大家介绍AnyChat的视频会议程序,涉及到anychat相关知识,对anychat视频会议相关知识感兴趣的朋友一起学习吧
    2016-01-01

最新评论