首页 > 代码库 > 设计模式随笔之——单列模式
设计模式随笔之——单列模式
一、单例模式的定义:
单例模式是一个比较简单的模式,其定义为:确保某一个类只有一个实例,而且自行实例化并像整个系统提供这个实例。单例模式大致可以分为:饿汉式和懒汉式。
以下关于单例模式的优点、缺点、使用场景摘自《设计模式之禅》
二、单例模式的优点:
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/
设计模式随笔之——单列模式