都有点记不起认识单例模式(也有叫单件模式的)是在什么时候了,有时候东西认多了不常用的话也经常抛之脑后甚至逐渐从大脑里被移除。不闲扯了,直接入正题吧。

什么是单例模式?

保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点.

单例模式的作用?

被指定的类在整个应用程序只会被创建一次.


接着我们用代码来加深对单例模式的理解。在这之前我们都知道如果一个类在没有使用单例模式的情况下是可以被实例化多次对象的,比如下面代码:

这里我先创建一个类:

  public class Person
{
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}

在应用程序中,我可以根据自己的需要无限的去实例化这个对象

 static void Main(string[] args)
{
for (int i = ; i < ; i++)
{
Person p = new Person();
}
}

这个时候我们开始把单例模式的思想带进来,首先我们思考第一个问题怎么实现这个类只会能被实例化一次对象。之所以我们现在可以无限去new这个对象是因为这个类当前有一个默认的public的构造函数,谁都能去拿

它来进行新的实例化。因此,这样也给我们带来一个解决问题的思路。看下面的代码,我在类中把默认的public构造函数给覆盖掉,自己写一个构造函数然后把尝试把访问修饰符改为private

public class Person
{
private Person()
{
}
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}

这个时候在外部去创建这个对象时就会出问题了。"....不可访问,因为...受保户级别限制"

这个时候虽然无法在外界创建这个对象,但是我们依然可以通过类的内部去创建对象。(在类中可以定义一个方法,这个方法就是用来创建这个对象)这样我们从外界就可以直接通过这个类的方法来创建对象了

这里需要注意的是我们在类中定义创建对象的方法必须为静态方法,这样外界只能通过这个类来实例对象,而不需要再new一个对象再调用这个内部方法。代码如下:

class Program
{
static void Main(string[] args)
{
Person p1 = Person.GetInstance();
}
}
public class Person
{
private Person()
{ }
public static Person GetInstance()
{
return new Person();
}
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}

这个时候依旧存在一个问题,我们依旧可以创建N此对象。这样就跟单例模式的思想不沾边了。接下来我们可以继续在这个类去加一个对象的判断,请看下面的代码

 public class Person
{
private Person()
{ }
private static Person _instance =null; public static Person GetInstance()
{
if (_instance == null)
{
return new Person();
}
return _instance; }
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}

这个时候我们在这个类中加入静态成员,而静态成员在应用程序中只共享一个类,当第一次调用GetInstance()方法的时它为null,然后满足条件后返回一个新的对象给用户。当第二次进来时,就不会null了,直接

把第一次的的对象返回给用户。解下来我们来测试下这个单例模式的雏形吧,测试结果:

这样就完成了一个基本的单例模式了,但这样还是完全不够完美的。毕竟这种实现无法满足多线程的场景。先撇开这个问题,先来总结下单例模式的实现思路:

把构造函数变成私有的外界就无法随便调用,然后在类中自己创建一个方法,在这个方法中new出一个对象,因为这个方法是要new对象的,所以说这个方法不能为实例方法,只能是静态方法。

静态方法每次被调用它就会new一次对象,这样就不是单例模式,所以还需要在这个类中加入一个静态的字段,这个字段就是这个类本身的类型。然后在这个类中判断这个静态字段为null就实例

化一个对象,然后返回。下次再调用的时候就不会为null了

好了,到这边已经解决了我们最开始的问题了。时间过的好快,(快十二点半了!!抓紧!人真是有点贱,玩游戏看电视不在乎多晚,想正儿八经写个文章就关注时间了)接下来看如何去处理多线程的单例模式。

 public class Singleton
{ public Singleton()
{
Console.WriteLine(".");
}
private static Singleton _instancce;
private static readonly object syn = new object();
public static Singleton GetInstance()
{ if (_instancce == null) //当对象为null时就锁定
{
lock (syn) //锁定
{
if (_instancce == null) //防止多个线程同时访问
{
_instancce = new Singleton();
return _instancce;
} }
}
return _instancce; }
}

这是通过加锁的方式来处理多线程访问问题,代码不难。这边简单解释下为什么要有两个对象的判断,先从第一个对象来说,因为一旦一开始加锁,代码就会被锁定同时只会有一段代码在执行,这样会影响代码执行性能。所以在锁定之前先去判断对象是否为 null ;第二个判断为 null 的原因是第一个判断不在这个线程中,表示只要满足条件都可以进入,之后的原因参考以上代码注释即可。

临睡之前突然想到还有个办法也能实现单例模式,可以利用 c# 静态字段,在第一次使用类的时候只初始化一次的特性。代码如下:

 public class Singleton2
{ private Singleton2()
{
Console.WriteLine(".");
} public static readonly Singleton2 _instance = new Singleton2();
public static Singleton2 GetInstance()
{
return _instance;
}
}

好了,就写到这儿了~good 9

c# 单例模式[Singleton]之深夜闲聊的更多相关文章

  1. 设计模式之单例模式——Singleton

                        设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...

  2. 【白话设计模式四】单例模式(Singleton)

    转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factor ...

  3. ooad单例模式-Singleton

                                                单例模式Singleton 主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 比如建立目录 ...

  4. iOS单例模式(Singleton)写法简析

    单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 1.单例模式的要点: 显然单例模式的要点有三个:一是某个类只能有一个实例: ...

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

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

  6. 设计模式之——单例模式(Singleton)的常见应用场景

    单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此 ...

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

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

  8. 设计模式(4) -- 单例模式(Singleton)

    设计模式(4)  -- 单例模式(Singleton) 试想一个读取配置文件的需求,创建完读取类后通过New一个类的实例来读取配置文件的内容,在系统运行期间,系统中会存在很多个该类的实例对象,也就是说 ...

  9. IOS单例模式(Singleton)

    IOS单例模式(Singleton)   单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 1.单例模式的要点: 显然单例模 ...

随机推荐

  1. Android问题-selection contains a component,button7,introduced in an ancestor and cannot be deleted.

    问题现象: 在开发Android时增加的控件想删除,可是删除时提示“Android问题-selection contains a component,button7,introduced in an ...

  2. Delphi监视进程并结束进程

    监视进程并结束进程在很多地方都用到这里借前人的经验写了个小例子: 以QQ的进程qq.exe为例 关键代码如下: function CheckTask(ExeFileName: string): Boo ...

  3. (Relax DFS专题1.2)POJ 2386 Lake Counting(使用DFS来计算有多少坨东西是连通的)

    题目大意:有N*M的矩阵稻田,'W'表示有积水的地方, '.'表示是干旱的地方,问稻田内一共有多少块积水,根据样例很容易得出,积水是8个方向任一方向相连即可. 题目大意:有N*M的矩阵稻田,'W'表示 ...

  4. 【STL源码学习】细品vector

    第一节:vector简介 vector是一种典型的类模板,使用的时候必须进行实例化. vector的数据存储在数组上,支持随机访问迭代器,支持下标操作[]和at操作,支持手动扩容和自动容量增长. ve ...

  5. C#程序实现动态调用DLL的研究

    摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...

  6. Java基础学习中一些词语和语句的使用

    在Java基础学习中,我们刚接触Java会遇到一些词和语句的使用不清的情况,不能很清楚的理解它的运行效果会是怎么样的,如:break,continue在程序中运行效果及跳转位置, 1.先来看看brea ...

  7. UIDatePicker 之显示中文 年月日

    picker_start=[[UIDatePicker alloc]initWithFrame:CGRectMake(centerView.frame.size.width/-,centerView. ...

  8. Codeforces Round #319 (Div. 1) B. Invariance of Tree 构造

    B. Invariance of Tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/576/ ...

  9. JFinal之学习资源

    JFinal官网: http://www.jfinal.com/ JFinal在线API: http://tool.oschina.net/apidocs/apidoc?api=jfinal JFin ...

  10. Gearman + Nodejs + MySQL UDF异步实现 MySQL 到 Redis 的数据同步

    [TOC] 1, 环境 CentOS, MySQL, Redis, Nodejs 2, Redis简介 Redis是一个开源的K-V内存数据库,它的key可以是string/set/hash/list ...