[程序员的自我修养-做一个牛逼的程序员,就得从设计模式入手]-单例模式

做任何事情都要先问一次为什么要这么做,可不可以换一个更容易的,甚至可以不这样做吗?开始会很难,但越往后活得越通透。

想看大而全的总结式文章的道友可以去百度道场,毕竟这篇文章只是我个人的学习总结。里面的说法,理解你我各有不同。能耐心看完的,也是十分感激,拜谢!

自己也算是做了2年多的码农了,总觉得自己码砖时,在看源码时,总会看到很多源码中使用了多种多样的设计模式,不由得给先贤们竖起了拇指,觉得技不如人的地方太多了。所以懵逼地开始学习设计模式这个代码界的《易筋经》。待他日功成,小可面向工资编程的水平也能高人一等。

闲话不多说。自己第一个看的就是单例模式了。

上面的只是废话,正文从这看。

看了很多别人的文章,我个人总结就是:单例模式就像是家里只请了一个保姆,炒菜,洗衣都是她。有事儿没事喊一声就行,我不管你的菜是在哪里买的,怎么买的。如果请了多个,那几保姆还得讨论一下谁去买菜,谁做饭(效率低)。请的人一多,你要付的工钱不也多嘛(内存资源消耗大)。所以,单例模式,在需要大量相同对象的场景下,能够小而精地完成你给他指的任务。现实的例子,微软系统中常见的任务管理器,就是一个单例模式。如果一下子在你屏幕上出现200个这样的窗口,你可能要骂街了:我靠,熊猫又烧香了?

先说说在哪些场合可以用单例。同一个资源被多方调用,我就可以把调用者都封装成一个单例,这样就只有这一个对象可访问资源,谁都不可以绕过它去创建对象(想想上学时的宿管大妈,十分的形象)。比如:日志记录如果有两个入口,那么日志内容要么少,要么重。单例可以保持数据的唯一性和正确。常用的线程池也是一个例子,所有对数据库的访问都由线程池打理。

面试的时候,能够快速回忆出单例模式的三要素:私有的静态变量,私有构造,公共入口(俩儿私家车一公共汽车)。枚举方式不适用这条,但更简单。

以上的三个点对于单例来说是最重要的了。其它的对于多线程、资源占用的优化都是细节了。

以下细说。

单例如同宝剑,有优劣之分。

木剑:饿汉式(静态预加载)。面试官如果说随便写一个单例,用它就可以了。绝对够用。

public class SingletonObject{
//私有属性放对象
private static SingletonObject instant = new SingletonObject();
//构造也是私有的,谁也不能让我乱生孩子了
private SingletonObject () {};
//留一个入口方法,永远指向我的独生子
public static SingletonObject getInstant() {
return instant;
}

}

以上种写法保证了线程安全。但是在类加载时就初始化instant,这就可能通过其它方式装载类时,也会发生初始化,会产生资源泿费甚至内存溢出。

铁剑:内部类式。下面这种方法也是线程安全的。同时也能保证lazy loading 的效果,节约内存开支。请看。

public class SingletonObject {
       //核心代码,用于创建实例
     private static class InstantHolder {
     private static final SingletonObject INSTANT = new SingleObject();
} 
     private SingletonObject() {}
     public static final SingletonObject getInstant() {return InstantHolder.INSTANT;}  
}

无剑:枚举式。这是我要说的最后一种,它没有所谓的构造方法,私有关键字,都没有。它简洁,高深莫测,你可能看不出它是一个单例模式。

public enum SingletonObjetEnum {
    INSTANT;
    public void anyMethod() {}
}

枚举式的单例也是线程安全的,也是最简单的。同时在反序列化上有优势,能够在反序列化时防止创建新对象。

总结:很多文章上都写了五种创建单例的的方法:懒汉式、双重检索式(懒汉式pro版)、饿汉式、内部类式、枚举式。我文章里只提到了后三种。前两种都需要使用并发控制关键字,双重检索的代码比较难写。想全面了解的同学可以去自己搜一下。

不论是哪一种,请大家都自己在机器上脱稿写写。实践可以自己更有信心。不论面试还是什么。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值