设计模式 - 单例模式 Singleton Pattern

一、概念

确保一个类只有一个实例,并提供全局访问点,该类负责创建自身对象,同时保证仅单个对象被创建,且可直接访问(无需实例化)。

|----|-----------------------------------------|
| 优点 | 内存中仅一个实例,减少内存开销(如频繁创建/销毁的对象)。 |
| 优点 | 避免资源多重占用(如写文件操作)。 |
| 缺点 | 无接口,不能继承,与单一职责原则冲突(一个类需同时关心内部逻辑和实例化方式)。 |

1.1 不同单例区别

|---------|-------------------------------------------------------------------------|
| 饿汉单例 | 最简洁的实现,使用Kotlin的object关键字,类加载时就初始化实例,线程安全,适合简单的单例,不依赖外部参数,启动时就需要准备好的场景。 |
| 懒汉单例 | 延迟初始化,第一次使用时才创建实例,需要使用synchronized保证线程安全,适合初始化成本高,不常使用的单例。 |
| 双重校验锁单例 | 结合了懒加载和高效的线程安全,减少了同步块的开销,只有第一次初始化时才会进入同步块,适合高性能要求的多线程环境。 |
| 静态内部类单例 | 利用类加载机制保证线程安全,延迟初始化,只有在调用getInstance()时才会加载内部类,实现简洁,性能优良。 |
| 枚举单例 | 天然防止反射和序列化攻击,是最安全的单例实现,线程安全,实现简单,适合需要高度安全性的场景,但灵活性稍差。 |

1.2 Android 使用场景

|---------------|---------------------------------------------------------|
| Application实例 | 整个应用生命周期内唯一的Application对象,用于全局状态管理(如初始化第三方库、存储全局数据)。 |
| 工具类 | 如ToastUtil、LogUtil等工具类,通过单例避免重复创建,统一管理资源(如Toast的上下文引用)。 |
| 数据库助手类 | SQLiteOpenHelper通过单例确保数据库连接唯一,避免多实例导致的锁冲突或资源泄露。 |

二、实现

1.1 饿汉单例

Kotlin 复制代码
object Demo {
    const val NAME = ""
    fun show() {}
}

1.2 懒汉单例

Kotlin 复制代码
class Demo private constructor() {
    companion object {
        private var instance: Demo? = null
        //线程安全获取实例
        @Synchronized
        fun getInstance(): Demo {
            if (instance == null) instance = Demo()
            return instance!!
        }
    }
}

by lazy 版

Kotlin 复制代码
class Demo private constructor() {
    companion object {
        val instance by lazy { Demo() }
    }
}

1.3 双重校验锁单例

Kotlin 复制代码
class Demo private constructor() {
    companion object {
        // volatile确保多线程环境下的可见性
        @Volatile
        private var instance: Demo? = null
        fun getInstance(): Demo {
            // 第一次检查,避免不必要的同步
            if (instance == null) {
               synchronized(Demo::class.java) {
                   // 第二次检查,确保只创建一个实例
                   if (instance == null) instance == Demo()
               } 
            }
            return instance!!
        }
    }
}

1.4 静态内部类单例

Kotlin 复制代码
class Demo private constructor() {
    companion object {
        fun getInstance(): Demo = Holder.INSTANCE
    }
    private object Holder {
        val INSTANCE = Demo()
    }
}

1.5 枚举单例

Kotlin 复制代码
enum class Demo {
    INSTANCE;
    fun show(){}
}
相关推荐
%xiao Q10 小时前
GESP C++五级-202406
android·开发语言·c++
二哈喇子!11 小时前
JavaWeb+Vue分离项目实现增删改查讲解
android
2501_9445215911 小时前
Flutter for OpenHarmony 微动漫App实战:推荐动漫实现
android·开发语言·前端·javascript·flutter·ecmascript
2501_9445215912 小时前
Flutter for OpenHarmony 微动漫App实战:图片加载实现
android·开发语言·前端·javascript·flutter·php
新镜13 小时前
【Flutter】LTR/RTL 阿拉伯语言/希伯来语言
android·flutter·ios·客户端
初级代码游戏16 小时前
android开发:获取手机IP和UDP广播
android·udp·获取ip
阿杰 AJie17 小时前
MySQL 聚合函数
android·数据库·mysql
孟秋与你18 小时前
【安卓】开发一个读取文件信息的简易apk
android
42nf18 小时前
Android Launcher3添加负一屏
android·launcher3·android负一屏
LcVong18 小时前
老版本Android源码在新版本IDE打开的常规报错及解决方案
android·ide