Singlton设计模式
- 单例定义:
确保一个类只有一个实例,并提供全局访问点。
- 适用场景:
1.) 当系统中某个类必须仅有一个实例对象,同时访问该系统的所有访问者必须访问同一个实例对象时,且该对象实例自身占用资源又不大时。
2.) 在C/s应用程序中,当我们要保证某一个非模式窗口,只能显示一个实例时。
- 举例适用场景:
线程池(threadpool)、缓存(cache)、对话框、处理编好设置和注册表(registry)的对象、日志对象,充当打印机、显卡等设备的驱动程序对象。这些类对象只能有一个实例,如果造出多个实例,就会导致许多问题产生,例如:程序的行为异常、资源适用过量,或者是不一致的结果。
- 实现推荐方案:
/// <summary>
/// Description of SiteSettings.
/// </summary>
public class SiteSettings
{
private static SiteSettings instance=null;
private static object locker=new object(); private SiteSettings()
{
} public static SiteSettings Instance {
get {
if(instance==null)
{
Console.WriteLine("Install equals null.");
lock(locker)
{
if(instance ==null)
{
Console.WriteLine("new SiteSettings instance.");
instance=new SiteSettings();
}
}
}
return instance;
}
} private bool siteClosed=false; public bool SiteClosed {
get { return siteClosed; }
set { siteClosed = value; }
}
}
调用:
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!"); // TODO: Implement Functionality Here Console.WriteLine(SiteSettings.Instance.SiteClosed);
Console.WriteLine(SiteSettings.Instance.SiteClosed);
SiteSettings.Instance.SiteClosed=true;
Console.WriteLine(SiteSettings.Instance.SiteClosed); Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
运行结果:
- 其他实现方案:
1.) 方案1
/// <summary>
/// Description of MemberBO.
/// </summary>
public class SiteSettings
{
private static SiteSettings instance=null;
private static object locker=new object(); private SiteSettings()
{
} public static SiteSettings Instance {
get {
if(instance ==null){
Console.WriteLine("Install equals null.");
lock(locker){
Console.WriteLine("Enter locker.");
Console.WriteLine("new SiteSettings instance.");
instance=new SiteSettings();
}
}
return instance;
}
} private bool siteClosed=false; public bool SiteClosed {
get { return siteClosed; }
set { siteClosed = value; }
}
}
2.) 方案2:
/// <summary>
/// Description of MemberBO.
/// </summary>
public class SiteSettings
{
private static SiteSettings instance=null;
private static object locker=new object(); private SiteSettings()
{
} public static SiteSettings Instance {
get {
Console.WriteLine("Install equals null.");
lock(locker){
if(instance ==null){
Console.WriteLine("Enter locker.");
Console.WriteLine("new SiteSettings instance.");
instance=new SiteSettings();
}
}
return instance;
}
} private bool siteClosed=false; public bool SiteClosed {
get { return siteClosed; }
set { siteClosed = value; }
}
}
3.) 方案3:
/// <summary>
/// Description of MemberBO.
/// </summary>
public class SiteSettings
{
private static SiteSettings instance=null;
private static object locker=new object(); private SiteSettings()
{
} public static SiteSettings Instance {
get {
Console.WriteLine("Install equals null.");
if(instance ==null){
Console.WriteLine("new SiteSettings instance.");
instance=new SiteSettings();
}
}
return instance;
}
} private bool siteClosed=false; public bool SiteClosed {
get { return siteClosed; }
set { siteClosed = value; }
}
}
4.) 方案4:
/// <summary>
/// Description of SiteSettings.
/// </summary>
public class SiteSettings
{
private static SiteSettings instance= new SiteSettings(); private SiteSettings()
{
} public static SiteSettings Instance {
get {
return instance;
}
} private bool siteClosed=false; public bool SiteClosed {
get { return siteClosed; }
set { siteClosed = value; }
}
}
5.) 方案5:
/// <summary>
/// Description of SiteSettings.
/// </summary>
public class SiteSettings
{
private static SiteSettings instance=null;
private static object locker=new object(); private SiteSettings()
{
} public static SiteSettings GetInstance() {
if(instance==null){
locker(locker){
if(instance==null){
instance=new SiteSettings();
}
}
}
return instance;
} private bool siteClosed=false; public bool SiteClosed {
get { return siteClosed; }
set { siteClosed = value; }
}
}
- 为什么不推荐方案1,方案2,方案3:
- 方案1,虽然考虑了线程安全,但还不是足够的安全,还没有双重锁定安全
- 方案2,虽然考虑了线程安全,但每次都要进入locker,即使instance对象已经赋值后
- 方案3,线程安全问题就没有考虑。
- 适当的情况下可以选择方案4,方案5
- 方案4,使用“迫切”创建实例(当应用程序启动,初始化系统时,初始化全局变量时创建对象实例),而不用延迟实例化的方法
- 方案5,采用了延迟实例化的方法。
- 注意混淆问题:
不要和Monitor,ReaderWriterLockSlim等这些线程安全的使用方式混淆。
1.) Monitor:提供同步访问对象的机制。
2.) ReaderWriterLockSlim:表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问。
- 优缺点:
1.)优点:
a.)确保了系统中保存一个实例对象,为程序带来了开拓思路;
b.)内存开销可能会占用一定空间,但它避免了每次都需要开辟空间的消费;
c.)使得程序能逻辑清理,开发者可以单一的使用该实例对象去操作,而不别每次都要new一个实例对象来进行操作。
2.缺点:
a.)多个用户在操作这个对象时,线程的安全性,就需要考虑。
b.)一直在占用资源,而不可以被回收。
参考资料:《Head First 设计模式》
欢迎拍砖!请牛人们给指点。
Singlton设计模式的更多相关文章
- MVVM设计模式和WPF中的实现(四)事件绑定
MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- java EE设计模式简介
1.何为设计模式 设计模式提供了对常见应用设计问题的解决方案.在面向对象的编程中,设计模式通常在解决与对象创建和交互相关的问题,而非整体软件架构所面对的大规模问题,它们以样板代码的形式提供了通用的解决 ...
- 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式
上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...
- 《JavaScript设计模式 张》整理
最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...
- 《JavaScript设计模式与开发实践》整理
最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...
- 设计模式之行为类模式大PK
行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...
- .NET设计模式访问者模式
一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...
- Java开发中的23种设计模式详解
[放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...
- java 设计模式
目录: 设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计 ...
随机推荐
- Windows上python开发--2安装django框架
Windows上python开发--2安装django框架 分类: 服务器后台开发2014-05-17 21:22 2310人阅读 评论(2) 收藏 举报 python django 上一篇文章中讲了 ...
- linux下mysql定时备份数据库
linux下mysql定时备份数据库 (2010-10-21 12:40:17) 转载▼ 标签: 杂谈 一.用命令实现备份 首页进入mysql的bin目录 1.备份数据#mysqldump -uu ...
- 开放平台鉴权以及OAuth2.0介绍
OAuth 2.0 协议 OAuth是一个开发标准,允许用户授权第三方网站或应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的内容. OAuth 2.0 ...
- 【IOS笔记】Delegation
Delegation Delegation is a simple and powerful pattern in which one object in a program acts on beha ...
- 【转载】Linux系统与性能监控
原文地址:http://kerrigan.sinaapp.com/post-7.html Linux System and Performance Monitoring http://www.hous ...
- Ubuntu 14.04 为 root 帐号开启 SSH 登录
1. 修改 root 密码 sudo passwd root 2. 以其他账户登录,通过 sudo nano 修改 /etc/ssh/sshd_config : xxx@ubuntu14:~$ su ...
- hdf第一周完了,突然时间静止.,醒了就早点去公司上班,再努力一点
周一要了个任务,做评价完成,分享完成的页面,做到周四发现可能做不出来,找dzy,逻辑比较混乱,想要放弃了,感觉自己非常没用.昨天跟豆聊了一下,否定自己是一点意义也没有的,觉得自己很差劲,无助的感觉跟初 ...
- MyEclipse 使用快捷键
将光标移到文档末尾,ctrl+end将光标移到文档首,ctrl+home行首,home行尾,end.
- How to pass selected records from form to dilog in AX 2012
static void main(Args args) { FormDataSource formDataSource; ; if(args.record().TableId == tablenum( ...
- iOS FMDB官方使用文档 G-C-D的使用 提高性能(翻译)(转)
由于FMDB是建立在SQLite的之上的,所以你至少也该把这篇文章从头到尾读一遍.与此同时,把SQLite的文档页 http://www.sqlite.org/docs.html 加到你的书签中.自动 ...