Kotlin smart proxy pattern

How to write a smart proxy pattern in Kotlin

An example of a smart proxy pattern in Kotlin.

Table of contents for design patterns in Kotlin

Smart proxies add extra functionality to the calls to the real object’s members. This functionality is often invisible to the client object. For example, counting the existing references to a resource-intensive object so that when the counter reaches zero the object’s data can be removed from memory. You could also use a smart proxy to log calls to the underlying object’s members. Wikipedia blackwasp.co.uk

Example:

UserService

interface UserService {

    fun createUser()

    fun deleteUser()

    fun updateUser()
}

MeasureUserService

class MeasureUserService(private val userService: UserService) : UserService {
    override fun createUser() {
        measure("createUser") { userService.createUser() }
    }

    override fun deleteUser() {
        measure("deleteUser") { userService.deleteUser() }
    }

    override fun updateUser() {
        measure("updateUser") { userService.updateUser() }
    }

    private fun measure(blockName: String, block: () -> Unit) {
        println("\tblock $blockName time: ${measureTimeMillis(block)} millis")
    }
}

Usage:

fun main() {
    val realUserService = RealUserService()
    val measureUserService = MeasureUserService(realUserService)

    realUserService.apply {
        createUser()
        updateUser()
        deleteUser()
    }

    measureUserService.apply {
        createUser()
        updateUser()
        deleteUser()
    }
}

Result

createUser
updateUser
deleteUser
createUser
	block createUser time: 42 millis
updateUser
	block updateUser time: 28 millis
deleteUser
	block deleteUser time: 12 millis