您的位置:首页 > 其它

.NET2.0设计模式 (.NET 2.0 Patterns) 1 -- 单件模式(Sington Patterns)

2009-01-04 21:20 183 查看
为什么要使用单件模式(Why use Singleton pattern)

我以前开发过一个OA系统,里面有个工作流子系统。工作流是一个很复杂的系统,采用CS架构开发最好了,但是现在要采用BS架构。BS架构对状态的处理是一个弱点。这个任务流系统需要实现任务流自定义,就是用户可以设计一个流程。谁执行,谁审核,通知谁都是自定义的。那么在定义这个流程的时候不可能一个页面就定义完,需要在多个页面之间传递数据。我们最先想到的办法就是采用Session或者Application。但是它们的不稳定性,他们的会释放都是让人头疼的。还有一个问题,如果系统运行了很久,一个企业每天都有很多工作流需要处理,那么工作流这个表的数据就是近百万条,而查找、修改工作流需要跨多个表的查询操作。并发多的时候难免造成数据库服务器死锁或者Down机。这个时候我就想起了CS架构的程序,所有的对象都不释放,随时可以访问,可以启动一个线程,选择一个合适的时机进行数据库读写。而BS架构很难做到。

那么采用BS架构就无法有效的保存状态了吗?答案是肯定可以。将我们原来的CS架构的工作流系统拿过来,编写全局的唯一的对象将整个系统运行起来。那么整个系统就是用这个全局的唯一的标识符来访问,他不会因为Web页面的释放而释放。说白了就是采用了单件模式。

真实世界里有很多单件模式,比如一说中国,肯定是说亚洲洲的中国,世界上只有一个中国,因此中国就是一个单件模式的例子。

什么是单件模式(What is Singleton pattern)

单件模式(Singleton Patterns)顾名思义就是一个类只有一个实例。也就是世界上只有一个中国,中国就是唯一的实例。这个事例可以有多个引用,比如说“China”可以引用中国,“中国”也可以引用中国。

如何实现单件模式(How to use Singleton pattern)

1、UML图



2、C#代码

2.1普通实现,首先将类的构造函数声明成私有的,然后生命一个静态的引用。这就是最简单的单件模式。

/// <summary>

/// 单件模式,线程不安全

/// </summary>

public class Singleton1

{

/// <summary>

/// 构造函数私有防止被外界实例化

/// </summary>

private Singleton1()

{ }

private static Singleton1 _Instance;

/// <summary>

/// 先判断字段是否为空,然后实例化或者返回

/// </summary>

public static Singleton1 Instance

{

get

{

if (_Instance == null)

{

_Instance = new Singleton1();

}

return Singleton1._Instance;

}

set

{

Singleton1._Instance = value;

}

}

}

看过了上面的代码,能发现有什么问题呢?那就是线程不安全,当地多个线程同时执行if (_Instance == null)语句的时候,都会new一个新对象,这样就不能保证是单件。

那么下面就是线程安全的单件模式

2.2线程安全但是惰性

/// <summary>

/// 单件模式,线程安全,但是惰性的

/// </summary>

public class Singleton2

{

private Singleton2()

{ }

/// <summary>

/// 直接实例化

/// </summary>

private static Singleton2 _Instance = new Singleton2();

/// <summary>

///

/// </summary>

public static Singleton2 Instance

{

get

{

return Singleton2._Instance;

}

set

{

Singleton2._Instance = value;

}

}

}

从上面的代码,可以看到,private static Singleton2 _Instance = new Singleton2();不论使用不使用该对象,这一句代码一定要执行的。因此我们说这种实现是惰性的。如果我们想采用不惰性的实现,请看下面的代码

2.3线程安全不惰性

public class Singleton3

{

private Singleton3()

{ }

private static Singleton3 _Instance;

/// <summary>

/// 由于在.NET中无法锁定空对象因在这里声明一个对象专门为了锁

/// </summary>

private static object _TheLock;

public static Singleton3 Instance

{

get

{

//首先判断单件是不是空

if (_Instance == null)

{

//锁定

lock (_TheLock)

{

//再次判断,请思考为什么要再次判断呢?

if (_Instance == null)

{

_Instance = new Singleton3();

}

}

}

return Singleton3._Instance;

}

set

{

Singleton3._Instance = value;

}

}

}
为什么要判断两次才行呢?在.NET环境下,不能锁定空对象。因此我们需要一个辅助对象来实现锁功能。但是锁住的对象不是我们需要的对象,因此要判断两次。

在什么场合使用单件模式(Where can use Singleton pattern)

单件模式的应用场合太多了。本人只能在这里发表一些愚见。根据我的开发经验,单件模式一般使用在根对象上。比如我写一个Word,那么表示Word应用程序的根对象采用单件模式。编写一个WindowsService,这个这个服务用一个对象管理起来,这个对象采用单件模式。

几点思考

1、单键模式就是类只有一个实例,不是说整个系统里就一个实例,在.NET环境下表示一个应用程序域内就一个对象。

2、您可以写一个单件模式的类,部署在两个应用程序中,一个控制台的。一个Winforms的,修改一个对象的值,您可以发现连个应用程序中的对象不是一个。

源码下载(Download code)

下载

返回目录
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: