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

单例模式,主要用于单线程,保证在应用程序中,一个类只有一个实例存在。有懒汉,和恶汉式区别。

public class Env() {

private Env env;

public Env getInstance(){

if(env==null){

env=new Env();

}

return env;

}

private Env(){

}

}

它的几种形式:

一般Singleton模式通常有几种种形式:

第一种形式: 定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。

public class Singleton {
private Singleton(){}
//在自己内部定义自己一个实例,是不是很奇怪?
//注意这是private 只供内部调用
private static Singleton instance = new Singleton();
//这里提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton getInstance() {
return instance;
}
}

第二种形式:

public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次
//使用时生成实例,提高了效率!
if (instance==null)
instance=new Singleton();
return instance; }
}

其他形式:

定义一个类,它的构造函数为private的,所有方法为static的。

一般认为第一种形式要更加安全些

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

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值