Implementation by delegation with a private property


#1

Implementation by delegation is a great feature that allows to use composition over inheritance and cut on boilerplate tremendously. Unfortunately, it is limited by the fact that it only allows primary constructor parameters and in-place created instances as delegates. In a lot of scenarios (if not in most scenarios!) the fact that current implementation is backed by another one should be an implementation detail:

interface Executor<Request, Response> {
    suspend fun execute(request: Request): Response
}

class Throttler<Request, Response>(
    private val base: Executor<Request, Response>,
    private val settings: ThrottlerSettings
) : Executor<Request, Response> {

    var requestsPerMinute: Int
        get() ...
        set() ...

    // ...
}

class SmartThrottler<Request, Response>(
    private val base: Executor<Request, Response>,
    ...
) : Executor<String, ByteArray> by throttler {

    // these settings are an implementation detail
    private val throttlerSettings = ThrottlerSettings(...)
    private val throttler = Throttler<String, ByteArray>(base, throttlerSettings)

    fun adjustRpm() {
        throttler.requestsPerMinute = computeRpm()
    }
}