• 第一式、单例模式-Singleton模式(创建型)


    一、简介

    单例模式主要用的作用是用于保证程序运行中某个类只有一个实例,并提供一个全局入口点。单例模式(Singleton)为GOF阐述的标准24种设计模式中最简单的一个。但随着时间推移,GOF所阐述的单例实现已不能完全满足实际应用。

    "ensure a class has only one instance, and provide a global point of access to it"

    二、动机(应用场景)

    几乎在每个应用程序中,都需要有一个从中进行全局访问和维护某种类型数据的区域。 在面向对象的 (OO) 系统中也有这种情况,在此类系统中,在任何给定时间只应运行一个类或某个类的一组预定义数量的实例。

    1、当使用某个类来维护增量计数器时,此简单的计数器类需要跟踪在多个应用程序领域中使用的整数值。 此类需要能够增加该计数器并返回当前的值。 对于这种情况,所需的类行为应该仅使用一个类实例来维护该整数,而不是使用其它类实例来维护该整数。
    2、每台计算机可以有若干个打印机,但只能有一个Printer Spooler,避免两个打印作业同时输出到打印机。
    3、PC机中可能有几个串口,但只能有一个COM1口的实例。
    4、系统中只能有一个窗口管理器。
    5.NET Remoting中服务器激活对象中的Sigleton对象,确保所有的客户程序的请求都只有一个实例来处理。
    6.应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。

    三、C#实现

    1、单线程实现

    单线程单例模式实现

    可以说是一个标准的单例的代码。

    优点:

    • 由于实例是在 Instance 属性方法内部创建的,因此类可以使用附加功能(例如,对子类进行实例化),即使它可能引入不想要的依赖性。

    • 直到对象要求产生一个实例才执行实例化;这种方法称为"懒实例化"。懒实例化避免了在应用程序启动时实例化不必要的 singleton

    缺点:

          多线程环境下它是不安全的。如果执行过程的不同线程同时进入 Instance 属性方法,那么可能会创建多个 Singleton 对象实例。每个线程都会执行下列语句,并决定必须创建新的实例。

    2、多线程实现

    多线程单例模式实现

    优点:由于实例的产生由自己控制,可以对非默认构造函数进行扩展、传参等操作。

    缺点:实现相对复杂

    3、C#简洁版

    由于 C# 与公共语言运行库也提供了一种"静态初始化"方法,这种方法不需要开发人员显式地编写线程安全代码,即可解决多线程创建等问题。

    简洁实现1

    更简洁的方式:

    简洁实现1

    因为静态构造函数是属于类的,而不属于任何一个实例,所以这个构造函数只会被执行一次,而且是在创建此类的第一个实例或引用任何静态成员之前,由.NET自动调用。

    1、由于静态构造函数由.NET调用,所以不需要public和private等访问修饰符。

    2、在创建第一个类实例或任何静态成员被引用时,.NET将自动调用静态构造函数来初始化类。(我们无法调用,也不知道它何时被调用)

    3、静态构造函数属于类,构造函数属于实例,他们并不冲突。静态构造函数只会运行一次。

    缺点:由于在此解决方案中由 .NET Framework 负责执行初始化,无法在实例化之前使用非默认的构造函数或执行其他任务。在大多数情况下,静态初始化是在.NET 中实现 Singleton 的首选方法。

    四、总结

    单线程版、多线程版、简洁版有各自的应用,没有那种实现是最好的。

    总结上述三种实现方法,以是否需要在创建单例实例时传参或执行其他任务分两类。即:

    1、不需要执行其他任务

    使用简洁版即可以保障在单线程、多线程都能安全使用的同时,代码量较少。

    2、需要

    一般情况下,均为单线程版。则使用单线程创建。若程序有多线程应用则应用使用双重检测的多线程实现。

    参考文档:

    http://msdn.microsoft.com/zh-cn/library/ff650316.aspx

    http://terrylee.cnblogs.com/archive/2005/12/09/293509.html

  • 相关阅读:
    Linux查看系统版本信息和设置远程终端登录
    Linux环境下安装JDK
    Windows10修改Tomcat服务端口和一台机器部署多个Tomcat
    [转]C#反射-Assembly.Load、LoadFrom与LoadFile进阶
    【转】C# lock的使用
    一个简单的C++程序及说明
    插入排序
    堆排序
    选择排序
    快速排序
  • 原文地址:https://www.cnblogs.com/kelite/p/3806733.html
Copyright © 2020-2023  润新知