设计模式之单例模式

单例模式定义

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

单例模式使用场景

避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一个。

对IO、数据库、网络、图片、SharePreference等的访问

需要定义大量的静态常量和静态方法,例如Utils类

唯一序列号生成的场合

需要一个共享访问点或者共享数据的场合,例如全局的计数器

Android中的SystemService就是通过单例的方式注册到系统当中

UML图

实现单例模式主要几个关键点

构造函数不对外开发,一般为private;

通过一个静态方法或者枚举返回单例类对象;

确保单例类的对象有且只有一个,尤其在多线程环境下;

确保单例类对象在反序列时不会重新构建对象;

单例模式的优点

当一个对象需要频繁地创建销毁时,单例模式可以减少内存开支,防止内存溢出。

当一个对象的产生需要比较多都资源时,如读取配置、产生其他依赖对象时,可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方法可以减少系统性能都开销。

可以避免对资源的多重占用,例如写文件操作,由于自由一个实例存在,避免了同时进行写操作。

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

单例模式的缺点

单例模式一般没有接口,扩展很困难,除非修改代码。

代理对象如果持有Context,会引发内存泄露,最好传Application Context。

实现的方式:

1.饿汉模式

2.懒汉模式

3.双检锁 DCL 实现模式

4.静态内部类单例模式

5.枚举模式

6.使用容器实现单例模式

7.Kotlin中通过object关键字实现

单例的总结

饿汉:无法对instance实例进行延迟加载;

懒汉:在添加同步的情况下才能保证实例的唯一性,但导致性能缺陷;

双检锁DCL:JVM即使编译器的指令重排序,有时实例不会唯一,使用volatile可以改变这个情况;

静态内部类和枚举:在延迟加载 / 线程安全 / 性能优势更为突出。

参考书籍

《Android 源码设计模式解析与实战》

或者扫一扫关注我的公众号

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181107G1JIQD00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券