设计模式随笔之——单列模式

一、单例模式的定义:

  单例模式是一个比较简单的模式,其定义为:确保某一个类只有一个实例,而且自行实例化并像整个系统提供这个实例。单例模式大致可以分为:饿汉式和懒汉式。

  以下关于单例模式的优点、缺点、使用场景摘自《设计模式之禅》

 

二、单例模式的优点:

  1、由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁的创建、销毁,而且创建或销毁时性能无法优化,单例模式的优势就更加明显。

  2、由于单例模式只生成一个实例,所以减少了系统性能开销,当一个对象产生需要较多资源时,如读取配置、产生其它依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方式来解决(Java EE中采用单例模式需要注意JVM的垃圾回收机制)

  3、单例模式可以避免对资源的多重占用,例如一个文件写入动作,由于只有一个实例存在,避免对同一个资源文件的同时写操作。

  4、单例模式可以在系统设置全局访问点,优化和共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理

 

三、单例模式的缺点:

  1、单例模式一般没有接口,扩展困难,若要扩展,除了修改代码基本没有第二张途径。单例模式为什么不能增加接口呢?因为接口对单例模式是没有任何意义,它要求“自行实例化”,并且提供单一实例、接口或抽象类是不可能被实例化的。当然,在特殊情况下,单例模式可以实现接口、被继承等,需要在系统开发中根据环境判断。

  2、单例模式对测试是不利的。在并行开发环境中,如果单例模式没有完成,是不能进行测试的,没有接口也不能使用mock的方式虚拟一个对象

  3、单例模式与单一职责原则冲突。一个类应该只实现一个逻辑,而不关心它是否是单例的,是不是单例要取决于环境,单例模式把“要单例”和业务逻辑融合在一个类中。

 

四、单例模式的使用场景:

  在一个系统中,要求一个类有且仅有一个对象,如果出现多个对象就会出现“不良反应”,可以采用单例模式

  1、要求生成唯一序列号的环境

  2、在整个项目中需要一个共享访问点或共享数据,例如一个web页面上的计数器,可以不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的

  3、创建一个对象需要小号的资源过多,如访问IO和数据库等资源

  4、需要定义大量的静态常量和静态方法(如工具类)的环境,可以采用单例模式(当然,也可以直接声明为static的方式)

 

五、饿汉式、懒汉式单例模式:

  1、饿汉式单例模式

 1 /**
 2  * 饿汉式单例模式,在类加载时就已经创建一个单例
 3  * 
 4  * @author Lion
 5  * 
 6  */
 7 public class Singleton {
 8 
 9     // 私有静态实例变量,在类加载时就已经创建完成
10     private static Singleton singleton = new Singleton();
11 
12     // 私有构造函数,保证不在类外部被访问
13     private Singleton() {
14     }
15 
16     // 公开的静态方法返回一个Singleton实例
17     public static Singleton getInstance() {
18         return singleton;
19     }
20 
21     public static void main(String[] args) {
22         // 输出,测试是否为同一个对象
23         for (int i = 0; i < 3; i++) {
24             System.out.println(Singleton.getInstance().toString());
25         }
26     }
27 }

  2、懒汉式单例模式

 1 /**
 2  * 懒汉式单例模式,只在第一次请求时创建一个实例,以后不在创建实例 但会出现线程不安全
 3  * 
 4  * @author Lion
 5  * 
 6  */
 7 public class Singleton1 {
 8 
 9     // 私有静态实例变量
10     private static Singleton1 singleton = null;
11 
12     // 私有构造方法
13     private Singleton1() {
14     }
15 
16     // 公开的静态工厂方法,返回该类的唯一实例(当发现没有实例没有初始化的时候才初始化)
17     public static Singleton1 getInstance() {
18         /**
19          * <pre>
20          * 线程不安全说明:
21          * 如果一个线程A执行到singleton = new Singleton1(),但还没有获得对象(正在初始化);
22          * 此时,线程B也执行到singleton == null,那么线程B的判断条件也为真,于是执行了singleton = new Singleton1();
23          * 最终,线程A获得了一个对象,线程B也获得了一个对象,故内存中就出现了两个对象
24          * </pre>
25          */
26         if (singleton == null) {
27             singleton = new Singleton1();
28         }
29         return singleton;
30     }
31 
32     public static void main(String[] args) {
33         System.out.println("没什么好测试的,线程安全只会出现在大量并发的情况下,低并发与饿汉模式一样");
34     }
35 }

 

  嗯,单例模式以我现在理解就这么点内容,如果有新的理解会补充的

 

作者:登天路

转载请说明出处:http://www.cnblogs.com/travellife/

posted @ 2014-11-04 12:27  登天路  阅读(399)  评论(0编辑  收藏  举报