I'm trying to do a Facade of my interfaces to abstract real types and omit need to name all of them directly. I ended up with this:
class Facade : ILeft by LeftImpl(), IRight by RightImpl()
ILeft
and IRight
are interfaces and I instantiate their implementations. This is in general solution I was looking for and it worked.
BUT
Let's say, I know, I will use most of the time only ILeft, or IRight. There are cases where I use them both, but most of the time, I'll use just one. Thus I would like to make them lazy, but how?
1) It's possible to use instance provided in the constructor, but that requires an instance.
2) If I try to define:
class Facade : ILeft by left, IRight by right {
val left by lazy { LeftImpl() }
val right by lazy { RightImpl() }
}
The left
and right
are inaccessible in the class declaration.
I can make the implementations lazy inside, that's also a possibility. But I'm trying to find a way, to write this out of the box, just by kotlin.
Any ideas how to have Facade object with just ILeft actually initialized by implementation?
Lazy properties lazy() is a function that takes a lambda and returns an instance of Lazy<T> , which can serve as a delegate for implementing a lazy property. The first call to get() executes the lambda passed to lazy() and remembers the result. Subsequent calls to get() simply return the remembered result.
Example. In this example, we will declare a lazy variable "myName" and we could see that the call to this parts of the code will happen only once and when the value is initialized, it will remember the value throughout the application. Once the value is assigned using lazy initialization, it cannot be reassigned .
Delegation (in computer science) is the assignment of authority from one instance to another. It can operate mutable as well as static relationship between classes, and inheritance, in turn, is based on the constant concept.
Simply, lazy creates an instance that performs initialization at the first access to the property value, stores the result, and returns the stored value.
Kotlin does not currently support implementing interfaces by delegating them to properties (KT-83), only constructor parameters can be used in expressions used in delegation, and these expressions are always evaluated at construction time.
So, indeed, you will likely need to define lazy proxy implementations for the interfaces:
class ILeftLazy(lazyLeft: Lazy<ILeft>): ILeft {
private val left by lazyLeft
override fun someLeftFun(): Foo = left.someLeftFun()
/* ... */
}
Then you can rewrite the Facade
primary constructor to accept Lazy
instances and implement the interfaces by delegation to the implementations:
class Facade(
lazyLeft: Lazy<ILeft>
lazyRight: Lazy<IRight>
) : ILeft by ILeftLazy(lazyLeft), IRight by IRightLazy(lazyRight) {
val left by lazyLeft
val right by lazyRight
}
You can then make the primary constructor private
and provide a no-arg secondary constructor that passes lazy { ILeftImpl() }
and lazy { IRightImpl() }
to the primary one.
This requires some boilerplate implementing the lazy proxy implementations but still allows you to implement the interfaces in Facade
by delegation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With