1. 概述

Singleton Pattren 要求一个类有且仅有一个实例,并且提供一个全局变量。这个创建的对象是独一无二的,在这个单独对象实例中,集中所创建类的所有属性和方法。
在创建一个单例,何时需要,这是程序设计的关键。从定义上可知这个类供全局调用,产品(程序)都可调用,所有是个全局静态变量,一般是不允许有派生类的。比如,火车的票数及票种,必须全局变量,这个往往是为了防止多线程调用时,导致问题溢出。

2. 模型图及思路

3. 代码实现

//单例模式类不能派生
public sealed class Singleton
{
//静态对象,才能在静态函数中访问
private static Singleton uniqueInstance; //线程安全控制实例
static object synobj = new object();
public static Singleton GetInstace()
{
//不加线程控制时,当两个线程同时运行GetInstance方法时,此时两个线程判断(uniqueInstance ==null)这个条件时都返回真,此时两个线程就都会创建Singleton的实例
// 当第一个线程运行到这里时,此时会对locker对象 "加锁",
// 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
// lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
lock(synobj)
{
// 如果类的实例不存在则创建,否则直接返回
//为创建实例时,进行创建
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
}
return uniqueInstance;
} //私有构造函数,只允许在此类中创建对象
private Singleton()
{
} }

以上的设计确实解决多线程的问题,但是上面的代码对于每个线程辅助对象locker枷锁后,在判断实例时候存在,对于这个操作完全没必要。可以当地一个线程创建实例后,后面的线程只需要直接判断是否为null。就如一下的代码。

//单例模式类不能派生
public sealed class Singleton
{
//静态对象,才能在静态函数中访问
private static Singleton uniqueInstance; //线程安全控制实例
static object synobj = new object();
public static Singleton GetInstace()
{
//不加线程控制时,当两个线程同时运行GetInstance方法时,此时两个线程判断(uniqueInstance ==null)这个条件时都返回真,此时两个线程就都会创建Singleton的实例
// 当第一个线程运行到这里时,此时会对locker对象 "加锁",
// 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
// lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
//只需要家这句判断就可以了
if(uniqueInstance == null)
{
lock(synobj)
{
// 如果类的实例不存在则创建,否则直接返回
//为创建实例时,进行创建
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
} //私有构造函数,只允许在此类中创建对象
private Singleton()
{
} }
public sealed class Singleton
{
static readonly Singleton instance=new Singleton(); static Singleton()
{
} Singleton()
{
} public static Singleton Instance
{
get
{
return instance;
}
}
}


看到上面这段富有戏剧性的代码,我们可能会产生怀疑,这还是Singleton模式吗?在此实现中,将在第一次引用类的任何成员时创建实例。公共语言运行库负责处理变量初始化。该类标记为 sealed 以阻止发生派生,而派生可能会增加实例。此外,变量标记为 readonly,这意味着只能在静态初始化期间(此处显示的示例)或在类构造函数中分配变量。

该实现与前面的示例类似,不同之处在于它依赖公共语言运行库来初始化变量。它仍然可以用来解决 Singleton 模式试图解决的两个基本问题:全局访问和实例化控制。公共静态属性为访问实例提供了一个全局访问点。此外,由于构造函数是私有的,因此不能在类本身以外实例化 Singleton 类;因此,变量引用的是可以在系统中存在的唯一的实例。
由于 Singleton 实例被私有静态成员变量引用,因此在类首次被对 Instance 属性的调用所引用之前,不会发生实例化。

4.要点知识

  1. Singleton模式是限制而不是创建。
  2. Singleton类中实例可以设置为Protected供子类派生
  3. Singleton考虑了对象创建的管理,没有进行销毁,就支持垃圾回收的平台,就不用对销毁进行管理。
  4. 优点:阻止其他对象实例化自己的副本,保证所有对象访问的唯一实例。
  5. 缺点:使用Singleton模式时,开发人员不能有new,进行实例化。

版权声明:本文为博主原创文章,未经博主允许不得转载。

NET设计模式-单例模式(Singleton Pattern)的更多相关文章

  1. 浅谈设计模式--单例模式(Singleton Pattern)

    题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ...

  2. 设计模式之单例模式(Singleton Pattern)

    单例模式 单例模式(Singleton Pattern)在java中算是最常用的设计模式之一,主要用于控制控制类实例的数量,防止外部实例化或者修改.单例模式在某些场景下可以提高系统运行效率.实现中的主 ...

  3. 乐在其中设计模式(C#) - 单例模式(Singleton Pattern)

    原文:乐在其中设计模式(C#) - 单例模式(Singleton Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 单例模式(Singleton Pattern) 作者:weba ...

  4. 设计模式系列之单例模式(Singleton Pattern)——确保对象的唯一性

    模式概述 模式定义 模式结构图 饿汉式单例与懒汉式单例 饿汉式单例 懒汉式单例 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 主要优点 适用场景 说明:设计模式系列文章是读刘伟所著 ...

  5. 【设计模式】单例模式 Singleton Pattern

    通常我们在写程序的时候会碰到一个类只允许在整个系统中只存在一个实例(Instance)  的情况, 比如说我们想做一计数器,统计某些接口调用的次数,通常我们的数据库连接也是只期望有一个实例.Windo ...

  6. 二十四种设计模式:单例模式(Singleton Pattern)

    单例模式(Singleton Pattern) 介绍保证一个类仅有一个实例,并提供一个访问它的全局访问点. 示例保证一个类仅有一个实例. Singleton using System; using S ...

  7. 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)

    在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...

  8. 十次艳遇单例设计模式(Singleton Pattern)

    1.引言 单例设计模式(Singleton Pattern)是最简单且常见的设计模式之一,在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访 ...

  9. 设计模式 单例模式(Singleton) [ 转载2 ]

    设计模式 单例模式(Singleton) [ 转载2 ] @author java_my_life 单例模式的结构 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类 ...

  10. 设计模式 单例模式(Singleton) [ 转载 ]

    设计模式 单例模式(Singleton) [ 转载 ] 转载请注明出处:http://cantellow.iteye.com/blog/838473 前言 懒汉:调用时才创建对象 饿汉:类初始化时就创 ...

随机推荐

  1. Quartz.NET开源作业调度架构

    Quartz.NET是一个开源的作业调度框架,是 OpenSymphony 的 Quartz API 的.NET移植,它用C#写成,可用于winform和asp.net应用中.它提供了巨大的灵活性而不 ...

  2. LINUX 添加定时任务

    LINUX 添加定时任务 crontab - l按 i:x 先按 esc然后 敲入 命令 :x*/5 3 * * 0 /root/ v.sh ..重启服务 service crond restart

  3. 《VTL语法参考指南》中文版[转]

    转自:http://blog.csdn.net/javafound/archive/2007/05/14/1607935.aspx <VTL语法参考指南>中文版 源文见 http://ve ...

  4. Java学习----集合函数

    1.List----有序的collection(序列) 与数组的不同:数据类型可以相同可以不同,数组的长度是预先定义好的,集合的长度也是预先定义好的,但是长度会随着元素的增加而增加 ArrayList ...

  5. javascrip 分享到

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. predis如何实现phpredis的pconnect方法

    predis和phpredis都是redis的php客户端,区别可以看这里,这里不赘述. phpredis是php扩展,由C语言编写,诞生较早,很多PHPer都熟悉. predis是用PHP语言编写, ...

  7. C# Winform C/S系统快速开发平台(源码+原创)

    C/S系统开发框架-企业版 V4.0 (Enterprise Edition) 简介: http://www.csframework.com/cs-framework-4.0.htm 适用软件:适合开 ...

  8. 2016022609 - redis哈希命令集合

    参考:http://www.yiibai.com/redis/redis_hashes.html Redis的哈希值是字符串字段和字符串值之间的映射,所以他们是表示对象的完美数据类型 在Redis中的 ...

  9. python相关的工具

    在使用python的时候,发现Adaconda工具包真的很不错,里面集合了很多的工具,并且,自带了很多的python常用模块 另外,PyCharm编辑器也是不错的,界面清晰,可以实现数据的可视化

  10. 【HDU3948】 The Number of Palindromes (后缀数组+RMQ)

    The Number of Palindromes Problem Description Now, you are given a string S. We want to know how man ...