MyException - 我的异常网
当前位置:我的异常网» 设计模式 » 【设计模式】单例模式-孤寂是一个人的狂欢

【设计模式】单例模式-孤寂是一个人的狂欢

www.MyException.Cn  网友分享于:2013-09-07  浏览:0次
【设计模式】单例模式-孤独是一个人的狂欢

单例模式

使用单例模式,可以确保在整个系统中仅有该类的一个实例。此外,单例模式的类会提供一个访问类实例的全局访问点。相比使用关键字 new来直接实例化一个对象 ,使用单例模式,将对象的创建"委托"给了类的一个静态方法。在该静态方法中实现对象的实例化并将其返回,同时该方法的执行过程也提供了控制实例化对象的时机。

 

1. 定义

  该模式确保一个类只有一个实例,并提供一个全局访问点。

 

2. 为什么需要

  对于一些类来说,只有一个实例是很重要的,且有些类只应该存在一个实例。比如,线程池、缓存、日志对象等。

  对于一些可以共享,并且非常耗费资源的对象,如果实例化多个对象,很显然会加重系统的负担。此外,它可能也不会带来收益,更甚可能引发一些问题。而对于那些在业务领域本应该只存在一个实例的领域对象,使用单例模式就更是理所当然了。

  就好比,国家规定了“一夫一妻”制度,如果你非得 new Wife(); 两次,那必然你的系统就会出问题。如果,在一个“国家”的作用域范围内,实例化了两个"主席"对象,那也会导致系统出现问题。

 

3. 实现方案

  虽然,单例模式实现的功效较为简单,但是在不同的场景下也提供了不一样的实现机制。

3.1 “延迟”式单例

  它的实例化对象只有在真正需要的时候,才会被创建。代码如下:

public class LazySingleton {
    
    private static LazySingleton singleton; //使用静态对象来存储唯一实例
    
    /*
        该构造器的访问描述符为 private,所以使得其他的类不可以通过构造器来直接实例化该对象。
        那么怎么来构造该类的对象呢?
        通过下面提供的静态方法,在其中通过调用这个私有的构造器来实例化对象。与此同时,在该方法中控制使得该类只能有一个实例化对象。
        当然,单例的构造器也是可以传入参数的。只需要在下面的实例化方法getInstance()中传入构造对象需要的参数,即可。
     */
    private LazySingleton() {
        
    }
    
    /*
        该方法实现了对象的构造,并控制使得只能构造一个实例化对象。
     */
    public static LazySingleton getInstance() {
        if (singleton == null) {
            singleton = new LazySingleton();
        }
        
        return singleton;
    }
}

  想要获得该单例对象,只需要使用静态方法 getInstance() 即可。该方法在多线程场景下不能保证只创建一个实例对象。如果存在两个线程A,B,且都需要获取该单例对象,则存在如下可能:

  1. 系统初始 singleton = null; 线程A和B分别调用 LazySingleton.getInstance(); 方法。
  2. 线程A执行 if 判断语句,条件为 true ,进入 if 代码块。且线程调度切换到线程B执行。
  3. 线程B执行 if 判断语句,此时 singleton 依然为 null ,因此进入 if 语句块,并实例化了一个单例对象,并返回。
  4. 切换到线程A,线程A直接调用 new 构造另一个单例对象,并返回。
  5. 此时,A、B线程返回不同的实例对象。

3.2 “饥饿”式单例

  对于某些对象,如果在创建和运行时的负担不太重,你想要急切的创建此单例,那么可以使用该方式来实现单例。代码如下:

public class HungrySingleton {
    private static HungrySingleton singleton = new HungrySingleton(); // 直接创建唯一实例
    
    private HungrySingleton() {
        
    }
    
    /*
        获取对象的唯一访问点
     */
    public static HungrySingleton getInstance() {
        return singleton; // 每次直接使用已创建的实例对象返回
    }
}

  该方法在静态初始化中创建单例对象,可以保证线程安全

3.3 “双重检查加锁”式单例

  该方法可以避免在多线程场景下,在系统中出现单例类的多个实例的情况。代码如下:

public class DoubleCheckSingleton {

    private volatile static DoubleCheckSingleton singleton; // volatile 修饰符保证变量在多线程之间的可见性

    private DoubleCheckSingleton() {}

    public static DoubleCheckSingleton getInstance() {
        if (singleton == null) {  // 检查实例,如果不存在就进入同步区
            synchronized (DoubleCheckSingleton.class) {
                if (singleton == null) { // 进入同步区后在检查一次,如果还是为null,才创建对象
                    singleton = new DoubleCheckSingleton();
                }
            }
        }
        return singleton;
    }
}

  这种方法,可以“最小化”同步代码块,可以减少时间的耗费,提高性能。

 

4. 总结

  单例模式可能是所有设计模式中最简单的一种了,但是它却是实际应用中很有可能碰到的一种设计模式。它简单,也简约,但威力不小。它存在如下优点:

  1. 对唯一实例的受控访问
  2. 缩小命名空间,该模式是对全局变量的一种改进,避免了使用那些存储唯一实例的全局变量来污染命名空间。
  3. 允许对操作和表示的精化。
  4. 允许可变数目的实例。事实上,可以在 getInstance() 方法中控制实例化多个对象。对象数为1,可以视为一种特例。

 

  孤独是一个人的狂欢。在整个系统中,单例对象都只存在一个,相比存在很多同胞的 Person, Student 等类对象它是孤独的,但这也突显了它在系统的重要地位。它就好比“濒危物种”。与此同时,所谓能力越大责任越大,因为没有同伴来分担压力,所以所有与该类的"交流"都需要该单例对象来完成,这也证明了它的“能力强大”。

  对于程序员而言,想要保持竞争力,事实上就是一个向着“单例”对象发展的过程。在团队里,如果你在某方面是独一无二的“对象”,那么你自然就无可取代。

  强行喂自己一口鸡汤:只有先经历一个人的孤独磨炼,才能享受和别人一起狂欢。

文章评论

漫画:程序员的工作
漫画:程序员的工作
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
Java程序员必看电影
Java程序员必看电影
10个调试和排错的小建议
10个调试和排错的小建议
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
总结2014中国互联网十大段子
总结2014中国互联网十大段子
程序员应该关注的一些事儿
程序员应该关注的一些事儿
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
程序员和编码员之间的区别
程序员和编码员之间的区别
程序员的鄙视链
程序员的鄙视链
编程语言是女人
编程语言是女人
那些争议最大的编程观点
那些争议最大的编程观点
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
我是如何打败拖延症的
我是如何打败拖延症的
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
我的丈夫是个程序员
我的丈夫是个程序员
代码女神横空出世
代码女神横空出世
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
如何成为一名黑客
如何成为一名黑客
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
 程序员的样子
程序员的样子
老程序员的下场
老程序员的下场
旅行,写作,编程
旅行,写作,编程
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
中美印日四国程序员比较
中美印日四国程序员比较
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
每天工作4小时的程序员
每天工作4小时的程序员
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
一个程序员的时间管理
一个程序员的时间管理
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有