我正在尝试对我的接口做一个Facade来抽象实型,并省略直接命名所有实型的需要。 我结束了:
class Facade : ILeft by LeftImpl(), IRight by RightImpl()
ILeft
和IRight
是接口,我将实例化它们的实现。这是我一直在寻找的通用解决方案,并且有效。
但是
比方说,我知道,我大部分时间只会使用ILeft或IRight。在某些情况下,我会同时使用它们,但大多数情况下,我只会使用其中一种。因此,我想让他们变得懒惰,但是如何?
1)可以使用构造函数中提供的实例,但这需要一个实例。
2)如果我尝试定义:
class Facade : ILeft by left, IRight by right {
val left by lazy { LeftImpl() }
val right by lazy { RightImpl() }
}
在类声明中无法访问left
和right
。
我可以使实现内部变懒,这也是可能的。但是我正试图找到一种方法,只用kotlin即可将其写出来。
有什么想法要让实际上只有ILeft实现的Facade对象通过实现初始化吗?
答案 0 :(得分:3)
Kotlin当前不支持通过将接口委托给属性(KT-83)来实现接口,只能在委托中使用的表达式中使用构造函数参数,并且始终在构造时对这些表达式进行求值。
因此,的确,您可能需要为接口定义惰性代理实现:
class ILeftLazy(lazyLeft: Lazy<ILeft>): ILeft {
private val left by lazyLeft
override fun someLeftFun(): Foo = left.someLeftFun()
/* ... */
}
然后,您可以重写Facade
主构造函数以接受Lazy
实例并通过委派给实现来实现接口:
class Facade(
lazyLeft: Lazy<ILeft>
lazyRight: Lazy<IRight>
) : ILeft by ILeftLazy(lazyLeft), IRight by IRightLazy(lazyRight) {
val left by lazyLeft
val right by lazyRight
}
然后,您可以使主要构造函数private
并提供一个无参数的辅助构造函数,该构造函数将lazy { ILeftImpl() }
和lazy { IRightImpl() }
传递给主要构造函数。
这需要一些实现延迟代理实现的样板,但仍然允许您通过委托在Facade
中实现接口。