An example of a cache proxy pattern in Kotlin.
Table of contents for design patterns in Kotlin
A cache proxy improves the performance of the underlying object’s members when they perform long-running tasks that return seldom-changing results. Wikipedia
Example:
PrimeNumberService
interface PrimeNumberService {
fun primeBefore(offset: Int, limit: Int): IntArray
}
CalculatePrimeNumberService
class CalculatePrimeNumberService : PrimeNumberService {
override fun primeBefore(offset: Int, limit: Int): IntArray = (0..limit).filter { it.isPrime() }.toIntArray()
private fun Int.isPrime(): Boolean {
for (i in 2..(this / 2)) {
Thread.sleep(10) // simulates a long time operation
if (this % i == 0) {
return false
}
}
return true
}
}
CachePrimeNumberService
class CachePrimeNumberService(
private var primeNumberService: PrimeNumberService
) : PrimeNumberService {
private val cache: MutableMap<Pair<Int, Int>, IntArray> = mutableMapOf()
override fun primeBefore(offset: Int, limit: Int): IntArray {
val key = Pair(offset, limit)
return cache[key] ?: primeNumberService.primeBefore(offset, limit).apply {
cache[key] = this
}
}
}
Usage:
fun main() {
val calculatePrimeNumberService = CalculatePrimeNumberService()
val cachePrimeNumberService = CachePrimeNumberService(calculatePrimeNumberService)
measureTimeMillis {
println(calculatePrimeNumberService.primeBefore(1, 100).joinToString())
}.also { time ->
println("calculatePrimeNumberService first call: $time millis")
}
measureTimeMillis {
println(calculatePrimeNumberService.primeBefore(1, 100).joinToString())
}.also { time ->
println("calculatePrimeNumberService second call: $time millis")
}
measureTimeMillis {
println(cachePrimeNumberService.primeBefore(1, 100).joinToString())
}.also { time ->
println("cachedPrimeNumberService first call: $time millis")
}
measureTimeMillis {
println(cachePrimeNumberService.primeBefore(1, 100).joinToString())
}.also { time ->
println("cachedPrimeNumberService second call: $time millis")
}
}
Result
0, 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
calculatePrimeNumberService first call: 7019 millis
0, 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
calculatePrimeNumberService second call: 7064 millis
0, 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
cachedPrimeNumberService first call: 7108 millis
0, 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
cachedPrimeNumberService second call: 0 millis