我正在编写一个框架,在其中难以编写需要由用户专用的通用单例类。
我希望用户能够编写如下内容:
class CustomClass protected constructor() : BasicClass()
该框架能够编写:
BasicClass.instance
返回BasicClass单例
并且用户能够写:
CustomClass.instance
返回相同的实例,但作为CustomClass单例实例。
我想到了两种可能性
案例1:单身人士由班级用户管理
class CustomClass private constructor() : BasicClass() {
private object Holder {
val INSTANCE = CustomClass()
}
companion object {
val instance: CustomClass by lazy {
Holder.INSTANCE
}
}
}
但是我在BasicClass方面没有实例引用,用户每次都需要实现单例。
案例2:Singleton由框架管理 我无法正确编写
预先感谢您的帮助。
答案 0 :(得分:0)
这里开箱即用,特别是因为实际上没有多少上下文需要这些类的外观。基本上,如果您希望框架处理单例,则需要执行以下两项操作之一:
BasicClass
的实现(在运行时,或者带有批注并进行代码生成)这可能是2的实现。
// This is the class that users of the framework want to extend
abstract class BasicClass
// This is the way both the framework and users can access the singleton instance
object Singleton {
// The way users can set how an instance of the desired class is constructed
var provider: (() -> BasicClass)? = null
set(value) {
if (field == null) {
field = value
} else {
throw IllegalStateException("You can only register one provider for Singleton")
}
}
val value: BasicClass by lazy {
provider
?.invoke()
?: throw IllegalStateException("You need to declare your instance provider")
}
inline fun <reified T : BasicClass> get(): T {
return value as? T
?: throw NullPointerException("Instance is of wrong type ${value.javaClass.name}")
}
}
现在,您框架的用户可以执行以下操作:
class CustomClass private constructor() : BasicClass() {
companion object {
val instanceProvider: () -> BasicClass = { CustomClass() }
}
}
并且,根据他们代码的生命周期,他们可以将类注册为
ClassInstance.provider = CustomClass.instanceProvider
最后,在您的框架中,您可以执行以下操作:
val basic: BasicClass = ClassInstance.get()
用户可以同时执行以下操作:
val basic: BasicClass = ClassInstance.get()
val custom: CustomClass = ClassInstance.get()