Skip to content

Instantly share code, notes, and snippets.

@xxfast
Created August 18, 2022 17:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xxfast/01608e3fb49bd0686702b88893f06b31 to your computer and use it in GitHub Desktop.
Save xxfast/01608e3fb49bd0686702b88893f06b31 to your computer and use it in GitHub Desktop.
Decorator / Proxy design pattern need not apply?
data class Request(val url: String)
data class Response(val code: Int, val body: String)
typealias Operation = (request: Request) -> Unit
typealias Input = (Request) -> Response?
typealias Output = (Request, Response) -> Unit
class Process(val output: Output? = null, val input: Input)
class Processor {
internal val processes: MutableList<Process> = mutableListOf(
Process { request: Request -> Response(200, "pong! ${request.url}") },
)
fun process(request: Request): Response {
val order: List<Process> = processes.reversed()
order.forEach { step ->
val response: Response? = step.input(request)
if (response != null) {
processes.forEach { process -> process.output?.invoke(request, response) }
return response
}
}
throw IllegalArgumentException("No processor to process $request")
}
}
fun Processor.decorate(operation: Operation) = apply {
processes += Process { request: Request -> operation(request); null }
}
fun Processor.proxy(input: Input, output: Output) = apply {
processes += Process(
input = { request: Request -> input(request) },
output = { request, response -> output(request, response) }
)
}
fun interface Logger { fun log(request: Request) }
fun Processor.log(logger: Logger): Processor = decorate { request -> logger.log(request) }
typealias Cache = MutableMap<Request, Response>
fun emptyCache(): Cache = mutableMapOf()
fun Processor.cache(cache: Cache = emptyCache()): Processor = proxy(
input = { request ->
val response: Response? = cache[request]
response
},
output = { request, response ->
cache += request to response
}
)
fun main() {
val request = Request("https://http.cat/200")
val processor = Processor()
.log { println("LOG: $it") }
.cache()
// Don't touch ✋
processor.process(request)
processor.process(request)
val response: Response = processor.process(request)
println(response)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment