设计模式初探-单例模式(Singleton)

Singleton模式,又称单例模式,它保证一个类仅有一个实例,并提供一个访问它的全局访问点。单例模式在平常开发中经常用到,比如系统的全局配置属性,常用的工具类或工厂方法都可以实现为一个单例。单例模式概念很简单,实现起来也不麻烦,但一不小心还是有可能出错的。

一、使用场景

只要是要求实例唯一的都可以使用单例模式来实现,特别是耗资源的实例!

二、UML图

单例模式uml图

三、Java实现

1、懒汉型

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package study.patterns.singleton;  
  2. /** 
  3.  * 单例模式:根据实例创建的时机与方式可分为 
  4.  * 懒汉型,饿汉型,双重检测型等 
  5.  * @author qbg 
  6.  *  
  7.  */  
  8. public class Singleton {  
  9.     private static Singleton instance = null;  
  10.     /* 
  11.      * 限制客户自己生成类实例的能力,不过通过java反射机制可以突破此限制 
  12.      */  
  13.     /** 
  14.      * 为用户提供统一的获取类实例的接口, 
  15.      * 此接口可以根据需求改变实现,即可以保持类实例的唯一, 
  16.      * 也可以维持多个类实例,这对用户来说是透明的。 
  17.      * @return 
  18.      */  
  19.     public static synchronized Singleton getInstance(){  
  20.         if(instance==null){  
  21.             instance = new Singleton();  
  22.         }  
  23.         return instance;  
  24.     }  
  25. }  
通过将instance暴露为public的静态的类属性也可以实现单例模式,但较工厂方法相比缺少灵活性,比如后期单例变多例。同时,由于静态类属性是通过类加载器保证实例的唯一性(instance在类装载时才会实例化),而类装载的时机有很多种,导致对实例的创建缺乏掌控。

懒汉型单例由于延迟了类实例的创建,只在真正需要时才创建,所以较饿汉型更适用,当然如果不需要考虑实例的懒加载那就无所谓了。对于耗资源,费时间的实例创建最好采用懒汉形式实现。

2、饿汉型

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package study.patterns.singleton;  
  2. /** 
  3.  * 单例模式:根据实例创建的时机与方式可分为 
  4.  * 懒汉型,饿汉型,双重检测型等 
  5.  * @author qbg 
  6.  *  
  7.  */  
  8. public class Singleton {  
  9.     /** 
  10.      * 这种方式基于classloder机制避免了多线程的同步问题, 
  11.      * 不过,instance在类装载时就实例化,而导致类装载的原因有很多种。 
  12.      * 在单例模式中大多数都是调用getInstance方法, 但不排除其他方式(比如调用其他的静态方法)导致类装载。 
  13.      */  
  14.     private static Singleton instance = new Singleton();  
  15.     /* 
  16.      * 限制客户自己生成类实例的能力,不过通过java反射机制可以突破此限制 
  17.      */  
  18.     private Singleton(){}  
  19.     /** 
  20.      * 为用户提供统一的获取类实例的接口, 
  21.      * 此接口可以根据需求改变实现,即可以保持类实例的唯一, 
  22.      * 也可以维持多个类实例,这对用户来说是透明的。 
  23.      * 由于类加载器机制避免线程同步问题,所以此处不需要再同步了 
  24.      * @return 
  25.      */  
  26.     public static Singleton getInstance(){  
  27.         return instance;  
  28.     }  
  29. }  

3、双重检测型

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package study.patterns.singleton;  
  2. /** 
  3.  * 单例模式:根据实例创建的时机与方式可分为 
  4.  * 懒汉型,饿汉型,双重检测型等 
  5.  * @author qbg 
  6.  *  
  7.  */  
  8. public class Singleton {  
  9.     private static Singleton instance = null;  
  10.     /* 
  11.      * 限制客户自己生成类实例的能力,不过通过java反射机制可以突破此限制 
  12.      */  
  13.     /** 
  14.      * 双重检测机制,确保懒加载又提高了性能。 
  15.      * @return 
  16.      */  
  17.     public static Singleton getInstance(){  
  18.         //先判断实例是否创建好了,如果好了直接返回  
  19.         if(instance == null){  
  20.             //如果实例没有创建好则同步实例创建过程.  
  21.             synchronized (Singleton.class) {  
  22.                 if(instance==null){  
  23.                     instance = new Singleton();  
  24.                 }  
  25.             }  
  26.         }  
  27.         return instance;  
  28.     }  
  29. }  
双重检测机制由于将同步过程最小化,且尽可能的减少同步次数,从而提高了性能。第一种实现方式每次通过getInstance()获取实例都需要同步,而这些同步只需在实例创建时才有用,大大浪费资源。不过双重检测机制在java 5后才能表现正确的行为,参考 http://www.ibm.com/developerworks/cn/java/j-dcl.html

4、枚举型

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package study.patterns.singleton;  
  2. /** 
  3.  * 利用java 1.5提供的枚举类型实现单例。 
  4.  * 此方式较其他实现方式更简洁,由于枚举无偿地提供序列化机制, 
  5.  * 绝对防止多次实例化,即使是在面向复杂的序列化或反射攻击的时候。 
  6.  * 不过这种方式只能在java 1.5后使用. 
  7.  * @author qbg 
  8.  */  
  9. public enum Singleton {  
  10.     INSTANCE;  
  11.     public void doSomething(){}  
  12. }  

四、模式优缺点

优点:

1、对唯一实例的受控访问,由于Singleton类将实例的个数及产生时间都封装了起来,而不是让客户自己生成,所以它严格的控制了客户怎样及何时访问实例。

2、缩小命名空间,单例模式是对全局变量的一种改进,减少了对命名空间的污染。对于java没多大用途,java里没全局变量的概念。

3、允许可变数目的实例,这个需要实现为工厂方法,静态实例的单例模式限制只能生成1个实例。


转载于:http://blog.csdn.net/qbg19881206/article/details/17768143

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值