c# 单例模式[Singleton]之深夜闲聊
都有点记不起认识单例模式(也有叫单件模式的)是在什么时候了,有时候东西认多了不常用的话也经常抛之脑后甚至逐渐从大脑里被移除。不闲扯了,直接入正题吧。
什么是单例模式?
保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点.
单例模式的作用?
被指定的类在整个应用程序只会被创建一次.
接着我们用代码来加深对单例模式的理解。在这之前我们都知道如果一个类在没有使用单例模式的情况下是可以被实例化多次对象的,比如下面代码:
这里我先创建一个类:
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]之深夜闲聊的更多相关文章
- 设计模式之单例模式——Singleton
设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...
- 【白话设计模式四】单例模式(Singleton)
转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factor ...
- ooad单例模式-Singleton
单例模式Singleton 主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 比如建立目录 ...
- iOS单例模式(Singleton)写法简析
单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 1.单例模式的要点: 显然单例模式的要点有三个:一是某个类只能有一个实例: ...
- 浅谈设计模式--单例模式(Singleton Pattern)
题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ...
- 设计模式之——单例模式(Singleton)的常见应用场景
单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此 ...
- 设计模式之单例模式(Singleton Pattern)
单例模式 单例模式(Singleton Pattern)在java中算是最常用的设计模式之一,主要用于控制控制类实例的数量,防止外部实例化或者修改.单例模式在某些场景下可以提高系统运行效率.实现中的主 ...
- 设计模式(4) -- 单例模式(Singleton)
设计模式(4) -- 单例模式(Singleton) 试想一个读取配置文件的需求,创建完读取类后通过New一个类的实例来读取配置文件的内容,在系统运行期间,系统中会存在很多个该类的实例对象,也就是说 ...
- IOS单例模式(Singleton)
IOS单例模式(Singleton) 单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 1.单例模式的要点: 显然单例模 ...
随机推荐
- Eclipse的DDMS File Explorer无法进入data目录解决方案
进入data目录需要root权限.所以,你的手机要有root才可以.然后做以下步骤就可以了 1.cmd进入platform-tools目录 2.adb shell 3.su(这里要看手机有没有请求ro ...
- [iOS基础控件 - 5.2] 查看大图、缩放图片代码(UIScrollView制作)
原图: 900 x 1305 拖曳滚动: 缩放: 主要代码: // // ViewController.m // ImageZoom // // Created by ...
- CSS定义选择器
ID与类 层叠 分组 继承 上下文选择器 子类选择器 其他选择器 结构与注释 20.1 ID与类 选择器是用于控制页面设计的样式.即ID选择器何类选择器. 一直以来,许多开发人员经常将ID与类混淆,或 ...
- sublime text3的一些小技巧记录(配gif图)
缓慢更新 1.同时操作多行数据. 示例: 选择你需要的块,然后按ctrl+shift+L键,然后再按end或者home键.
- Oracle用户及角色的权限管理[Oracle基础]
1.查看全部用户: select * from dba_users; select * from all_users; select * from user_users; 2.查看用户或角 ...
- android常见错误-The container 'Android Dependencies' references non existing library
The container 'Android Dependencies' references non existing library
- 传微软欲收购Xamarin:未来有望通过VS开发iOS和Android应用?
据CRN报道,其援引匿名人士的消息称,微软将收购一家创建C#移动应用工具的公司或进行注资,并且谈判已经到了最终阶段.这家公司的名字叫做Xamarin,创建于2011年.对于微软来说,收购Xamarin ...
- Codeforces Round #324 (Div. 2) E. Anton and Ira 贪心
E. Anton and Ira Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/584/probl ...
- memcpy内存拷贝及优化策略图解
一般内存拷贝与优化 代码实现 #include<iostream> usingnamespace std; //不安全的内存拷贝(当源内存地址与目标内存地址重叠时会产生错误) void h ...
- 手动配置Ubuntu Linux系列3-缺省网关和主机名
上一篇讲到[原创]手动配置Ubuntu Linux的DHCP客户端,这里再说一下配置静态IP地址的方法. 仍然是编辑 interfaces文件. $ sudo vi /etc/network/ ...