Singleton(单例)模式d

转自:http://hi.baidu.com/yshnjycwcsbchmd/item/b9629e9d6fe32c895914616b

写在前面的话:
本文介绍Singleton模式的原理及使用,主要代码使用JAVA实现.本文仅作抛砖引玉的作用,欢迎大家继续讨论。
因为Singleton(单例模式)的实现代码比较简单,因此我没有提供打包的可执行代码,不过,文中的代码直接可以编译执行。如果想自己测试Singleton,可以试着通过Object o1;Object o2的方式获取对象,然后再使用==运算符比较结果,以测试单例的状态。
如果有任何问题或建议,请联系<a href=">
##########################################################################
设计模式之Singleton模式
##########################################################################
Singleton模式
      原理及JAVA实现


作者:saharabear
来自:http://saharabear.openmotel.cn
版本:V0.1
分类:设计模式
TAG:设计模式,单例模式,Design Pattern, Singleton
摘要:Singleton模式是为了实现在整个应用程序中,某一个类只能有一个实例存在。比如,在一个WEB的应用程序中,应该只存在一个链接池(内部可能包含多个链接);或者应用程序建立一个文件夹等操作的时候,只能使用单线程操作,而不允许存在两个实例操作同样的内容。

目录
      1.什么是Singleton模式
      2.如何实现Singleton模式
      3.什么时候使用Singleton模式
      4.Singleton is evil or not?
      5.多线程及分布式下的Singleton
      6.总结
      7.关于本文
      8.更新日志
      9.参考文档
      10.相关文档

++++++++++++++++++++++++++++++++++++++++
正文
++++++++++++++++++++++++++++++++++++++++

1.什么是Singleton模式
      Singleton模式,是为了实现在一个应用程序中,某一个类只能有一个实例,也就是说只能产生一个对象。
  Singleton是一种创建型模式,这意味着,如果某个类采用了Singleton模式,则在这个类被创建后,它将只可能产生一个实例供外部访问,并且会提供一个全局的访问点。
  一眼看去,Singleton似乎有些像全局对象。但是实际上,全局对象和Singleton模式有本质的区别,这是因为大量使用全局对象会使得程序质量降低,而且有些编程语言根本就不支持全局变量。最重要的是传统的全局对象并不能阻止人们将一个类实例化多次。而Singleton模式则通过从根本上控制类的创建,将"保证一个类有且只有一个实例"这个任务交给了类本身。这一点是全局对象方法与Singleton模式的根本区别。

2.如何实现Singleton模式
      与其他所有的模式一样,Singleton模式只是一种理念,而具体的实现则有各种不同的方法。在这里,我知道的主要有下面四种方法:
      (1)使用静态方法来实现实例的创建
  这里要注意使用一个private的构造方法。如果不把构造器声明为private,java的编译器会自动同步一个默认的friendly构造器. 复制内容到剪贴板 代码:          public class Singleton {
              /*
               * private constructor to make sure nobody can create an 
               * object using it.
               */
              private Singleton(){};
              private static Singleton singleton; 
           /*
            * Global method for instancing of the class.
            */
           //make sure you use a static method
           public static synchronized Singleton getInstance() {
             if (singleton == null)
                singleton = new Singleton();
             return singleton;
           }

//other method
          }
(2)纯静态对象实现
  产生一个纯静态的对象,然后给出一个全局的访问点供其他的对象调用
  一般认为这种方式更安全一些。Jdon的板桥里人先生也是这种观点。 复制内容到剪贴板 代码:public class Singleton {
  private Singleton(){}
  //use private and static keywords
  private static Singleton instance = new Singleton();
  //Global access  
  public static synchronized Singleton getInstance() {
    return instance;   
   } 
}
(3)设置一个静态变量作为标志位
  这种方法的原理类似于第一种方法,只不过并不是判断singleton的实例是不是存在,而是另外设置一个标志位来判断。 复制内容到剪贴板 代码:
      public class Singleton {
          static boolean instance_flag = false; // true if a instance exist
          public Singleton() {
             if (instance_flag)
          {
          //define Exception    to throw
           }
           else{
             instance_flag = true; // false if no instance exist
           }
           }
          //other method
          }
(4)自定义Singleton生成器
  自己设计一个Singleton生成器,在一定程度上可以理解为工场模式的扩展。在这种方式下,可以转化Singleton的特点,甚至通过一定方式改变生成的Instance的数目(好像这样就不应该再叫Singleton,我见过有一种说法叫多例)。主要实现方法可以通过Hashtable或者相应的数据结构然后设置标志位和长度。
      有兴趣的可以仔细查一下这方面的资料,在多核或多CPU的情况下,使用这种方式会更好一些。

3.什么时候使用Singleton模式
      很多时候我们都会需要Singleton模式,最常见的比如我们希望整个应用程序中只有一个连接池实例等。但是,这种模式虽然简单,想用好却很不容易,需要考虑JVM,内存,线程,分布式等等情况。
      模式本来就是一个有很大不确定性因素的东西,因此,具体什么时候使用Singleton模式,需要非常小心,同时,也没有一个完整的评价标准来确定倒底什么时候使用Singleton模式。
      我个人的意见是,如果是一个容器内的应用,那么最好不要使用单例,如果需要使用,那么一定要注意分布式和多线程的问题。
      另外,关于lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了,上面除了第二种方法以外,应该都属于lazy initialization。这部分的知识我理解也不够深入,不过一定要使用synchronized,如果没有使用synchronized,那么使用getInstance()是有可能得到多个Singleton实例;同时,synchronized也有可能造成浪费过多的CPU资源在一些不必要的同步上。

4.Singleton is evil or not?
         很多人认为Singleton is evil。从设计上的角度来考虑,Singleton模式的引入会给程序带来一些不好的影响:
      (1)结合了静态方法,由于静态方法一般由类定义,而不是接口,导致系统中其他程序过分依赖该类本身(对该类的引用被硬编码到其他类中),增加了系统的耦合度;
      (2)由于静态方法和变量没有“继承”的概念,使该模式不利于扩展。
      (3)由于Singleton的创建完全在本类中完成,对外界封闭,每个不同的singleton必须拥有完全独立的初始化过程,需要独立处理自己的配置。在一个大的系统中,越来越多的singleton导致系统越来越难维护。
在这里,没法确定谁对谁错,在参考文档中有相关文档,可以仔细去仔细读一读。

5.多线程及分布式下的Singleton
  先说说多线程的情况下。一个单例的对象,在多线程的情况下,虽然也只有一个实例存在,但是,可能存在多个线程同时访问的情况。这时,就有可能产生混乱,以至于产生脏数据。
  然后,在分布式环境下,比如使用了EJB,那么面临的环境可能是多服务器,多个JVM在运行。这时,Singleton就已经失去所有意义了,因为在不同的JVM中,都可能产生一个单例,而这多个JVM又会组成一个应用。因此,要注意这一点。

6.总结
  总体上说,Singleton模式是GOF 23种设计模式中,最简单,但想用好却又非常复杂的一种模式,关于它的争论很多,不过,作为创建型的一种经典模式,只要用在最正确的地方,就可以带来很多的方便。而具体的度的把握,就需要个人的判断和理解了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值