简体   繁体   中英

Lazy class delegate in Kotlin?

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM