java带参数的单例_Kotlin带参单例模式的优雅实现
kotlin经典单例实现
我们都知道 Kotlin 为我们实现单例提供了很⽅便的实现,⼀个关键词就可以搞定:那就是 object
object SomeSingleton
反编译成 Java 代码:
public final class SomeSingleton {
public static final SomeSingleton INSTANCE;
private SomeSingleton() {
INSTANCE = (SomeSingleton)this;
}
static {
new SomeSingleton();
}
}
可以看出,是通过静态内部类实现的。它是《java并发编程实践》推荐的实现单例的⽅式。因为这种⽅式不仅能够保证单例对象的唯⼀性,同时也延迟了单例的实例化。
关于 java 的⼏种单例设计模式实现⽅法,可以参考笔者之前写的⼀篇博客:
带参优雅实现
⾃动化在带来快捷便利的同时,就意味着失去⼀定的灵活性。
object ⽅式的实现带来的⼀个局限就是不能⾃由传参。因为 Kotlin 的 object 关键字不允许存在任何构造函数。
或许你会想到可以通过注⼊的⽅式去实现,但是这样还是太⿇烦,如果忘记去调⽤这个⽅法就会出问题,相信他⼈也不太喜欢这样的⽅式去获取你写的单例对象。
有没有更为优雅的⽅式实现呢?
当然是有的。
我们需要参考 Kotlin 标准库中的 lazy() 函数的实现思路。
把创建和初始化带有参数的单例的逻辑封装起来。并通过双重检查锁定算法实现逻辑的线程安全。
open class SingletonHolder(creator: (A) -> T) {
private var creator: ((A) -> T)? = creator
@Volatile
private var instance: T? = null
fun getInstance(arg: A): T {
val i = instance
if (i != null) {
return i
}
return synchronized(this) {
val i2 = instance
if (i2 != null) {
i2
} else {
val created = creator!!(arg)
instance = created
creator = null
created
}
}
}
//对上述⽅法的⼀种更简洁的写法
fun getInstance2(arg: A): T =
instance ?: synchronized(this) {
instance ?: creator!!(arg).apply {
instance = this
}
}
}
这个类⼀撸完,它就像⼀个爸爸的存在。有了它接下来我们实现单例就变得异常简单,举个栗⼦我想实现⼀个带 context 参数的 SkinManager 单例
class SkinManager private constructor(context: Context) {
companion object : SingletonHolder(::SkinManager)
}
使⽤⽅式:
好了,游戏结束,就这么简单~
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论