工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 微软开发专栏 > 技术专题 > 正文
探究Singleton设计模式
[文章信息]
作者:Mark Townsend
时间:2004-08-02
出处:MSDN开发精选6月刊
责任编辑:方舟
[文章导读]
在本文中,我们将讨论Singleton模式,它包含在创造性模式系列中
advertisement
热点推荐
· Java加密和数字签名编程快速入门
· 在VB6中用命令行为模式控制GUI动作
· Excel图表向导详解
· 浅析各种计算机病毒应对方法
· 2月16日软件精选 春节文章精彩回顾
[正文]

上一页  1 2 3  下一页

  逻辑模型

  Singleton模型非常简单直观。(通常)只有一个Singleton实例。客户端通过一个已知的访问点来访问Singleton实例。在这种情况下,客户端是一个需要访问唯一Singleton实例的对象。图1以图形方式显示此关系。


  物理模型

  Singleton模式的物理模型也是非常简单的。但是,随着时间的推移,实现Singleton的方式也略有不同。让我们看一下原始的GoFSingleton实现。图2显示按设计模式所定义的原始Singleton模式的UML模型。


  我们看到的是一个简单的类图表,显示有一个Singleton对象的私有静态属性以及返回此相同属性的公共方法Instance()。这实际上是Singleton的核心。还有其他一些属性和方法,用于说明在该类上允许执行的其他操作。为了便于此次讨论,让我们将重点放在实例属性和方法上。

  客户端仅通过实例方法来访问任何Singleton实例。此处没有定义创建实例的方式。我们还希望能够控制如何以及何时创建实例。在OO开发中,通常可以在类的构造函数中最好地处理特殊对象的创建行为。这种情况也不例外。我们可以做的是,定义我们何时以及如何构造类实例,然后禁止任何客户端直接调用该构造函数。这是在Singleton构造中始终使用的方法。让我们看一下设计模式中的原始示例。通常,将下面所示的C++Singleton示例实现代码示例视为Singleton的默认实现。本示例已移植到很多其他编程语言中,通常它在任何地方的形式与此几乎相同。

  C++ Singleton示例实现代码

//Declaration
class Singleton{
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
}

// Implementation
Singleton* Singleton::_instance = 0;

Singleton* Singleton::Instance() {
if (_instance == 0) {
_instance = new Singleton;
}
return _instance;
}

  让我们先花点时间分析一下此代码。该简单类有一个成员变量,此变量是指向该类自身的指针。注意,构造函数是受保护的,并且只有公共方法才是实例方法。在实例方法实现中,有一个控制块(if),它检查成员变量是否已初始化,如果没有的话,则创建一个新实例。控制块中这种惰性初始化意味着仅在第一次调用Instance()方法时初始化或创建Singleton实例。对于很多应用程序,这种方法效果很好。但对于多线程应用程序,这种方法证明具有潜在危险的副作用。如果两个线程同时进入控制块,则可能会创建该成员变量的两个实例。要解决这一问题,您可能想只将重要部分放在控制块周围以确保线程安全。如果您这样做,则将对实例方法的所有调用进行序列化处理,并且可能会对性能产生不利影响(取决于应用程序)。正是由于这个原因,创建了此模式的另一个版本,它使用某种称为双重检验机制的功能。下一个代码示例显示使用Java语法的双重检验锁定。

  使用Java语法的双重检验锁定Singleton代码

//C++ port to Java
class Singleton
{
public staticSingletonInstance() {
if (_instance == null) {
synchronized (Class.forName("Singleton")) {
if (_instance == null) {
_instance = new Singleton();
}
}
}
return _instance;
}
protected Singleton() {}
private staticSingleton_instance = null;
}

  在使用Java语法的双重检验锁定Singleton代码示例中,我们直接将C++代码移植到Java代码,以便利用Java关键部分块(已同步)。主要差别是不再有单独的声明和实现部分,没有指针数据类型,并且采用了新的双重检验机制。双重检验发生在第一个IF块上。如果成员变量为空,则执行进入关键部分块,该块再次双重检验该成员变量。仅在通过此最终测试后,才会实例化该成员变量。一般来说,两个线程无法使用这种方法创建两个类实例。另外,因为在第一次检查时没有出现线程阻塞,所以对此方法的大多数调用不会由于必须进入锁定而导致性能下降。目前,在实现Singleton模式时,很多Java应用程序中都广泛使用这种方法。

  这种方法很巧妙,但也有瑕疵。某些优化编译器可以将惰性初始化代码优化掉或对其重新进行排序,并且会重新产生线程安全问题。


上一页  1 2 3  下一页

天极社区邀请您:写博客日记  上传相片   论坛聊天  订阅电子杂志  推荐网摘   免费图铃工具
笔名:   请您注意:

 遵守国家有关法律、法规,尊重网上道德,承担一切因您的行为而直接或间接引起的法律责任。

 天极网拥有管理笔名和留言的一切权利。
评论:
 
发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • .NET Web应用框架构建模式
  • .NET框架中基于角色的安全性
  • 基于.NET的多用户客户端设计
  • ADO.NET实用技巧两则
  • DataSet的数据并发异常处理
  • 使用ADO.NET设计数据库应用程序
  • 实例解说.Net构架下的加密编程
  • 从 .NET 程序集提供图像
  • VS.NET中构建数据库应用程序
  • 使用.NET智能版进行SIM编程
  • 中兴携手阿尔卡特 全球逐鹿CDMA
  • 用友总裁王文京:誓将ERP变成“大众消费”
  • 香港消费者委员会:数码相机最贵未必最好
  • 外电称中兴正评估西门子手机业务 或能并购
  • 国信办督战八大行业灾难备份 将出台国家标准
  • 中国IT企业走进欧盟 搭第六框架计划直通车
  • 美邦银行用户注意 警惕新型“钓鱼”邮件
  • 微软三年时间磨出新IE 具有更强大安全性能
  • Advertisement