Motivation: A request can be handled by one of several objects, and we don’t want to hard-wire which object handles it. The handler should be determined at runtime.
Intent: Pass a request along a chain of potential handlers until one of them handles it.
Each handler decides whether to process the request or pass it to the next handler in the chain.
abstract class Logger(private val next: Logger? = null) {
fun log(level: Int, message: String) {
if (canHandle(level)) write(message)
else next?.log(level, message)
}
abstract fun canHandle(level: Int): Boolean
abstract fun write(message: String)
}
class InfoLogger(next: Logger? = null) : Logger(next) {
override fun canHandle(level: Int) = level == INFO
override fun write(message: String) { println("INFO: $message") }
}
class ErrorLogger(next: Logger? = null) : Logger(next) {
override fun canHandle(level: Int) = level == ERROR
override fun write(message: String) { println("ERROR: $message") }
}