Kotlin 设计模式示例:高级水平
\n\n设计模式是软件开发中针对典型问题的经过验证的解决方案。如果您已经掌握了基础设计模式(单例、工厂、观察者),那么是时候进入下一个层次了。在本文中,我们将介绍四种高级设计模式——责任链、解释器、中介者和备忘录——并展示它们在 Kotlin 中的实现,同时考虑语言惯用语法(sealed class、扩展函数、lambda 表达式)。
\n\n1. 责任链(Chain of Responsibility)
\n\n目的: 允许请求沿着处理链顺序传递,直到其中一个处理程序处理该请求。
\n\n问题: 一个日志记录系统,其中不同级别(DEBUG、INFO、ERROR)的消息应由不同的日志记录器处理。
\n\nKotlin 实现:
\n\n// 抽象处理程序\nabstract class Logger(private val level: Int) {\n private var nextLogger: Logger? = null\n\n fun setNext(logger: Logger): Logger {\n this.nextLogger = logger\n return logger\n }\n\n fun log(level: Int, message: String) {\n if (this.level <= level) {\n write(message)\n }\n nextLogger?.log(level, message)\n }\n\n protected abstract fun write(message: String)\n}\n\n// 具体处理程序\nclass ConsoleLogger(level: Int) : Logger(level) {\n override fun write(message: String) = println("[控制台] $message")\n}\n\nclass FileLogger(level: Int) : Logger(level) {\n override fun write(message: String) = println("[文件] $message")\n}\n\nclass EmailLogger(level: Int) : Logger(level) {\n override fun write(message: String) = println("[电子邮件] $message")\n}\n\n// 使用示例\nfun main() {\n val logger = ConsoleLogger(1).apply {\n setNext(FileLogger(2))\n .setNext(EmailLogger(3))\n }\n logger.log(2, "警告:内存不足")\n // 输出:\n // [控制台] 警告:内存不足\n // [文件] 警告:内存不足\n}\n\nKotlin 中的优势: 借助 apply 和 setNext 的链式调用,代码显得简洁。也可以将抽象类替换为带有默认实现的接口。
2. 解释器(Interpreter)
\n\n目的: 定义语言的语法并解释该语言的句子。
\n\n问题: 需要解析并计算简单的算术表达式(例如 "3 + 5 - 2")。
\n\n使用 sealed class 的 Kotlin 实现:
\n\n// 抽象表达式\nsealed class Expression {\n abstract fun interpret(): Int\n}\n\n// 终结符表达式——数字\ndata class Number(val value: Int) : Expression() {\n override fun interpret() = value\n}\n\n// 非终结符表达式——运算\ndata class Add(val left: Expression, val right: Expression) : Expression() {\n override fun interpret() = left.interpret() + right.interpret()\n}\n\ndata class Subtract(val left: Expression, val right: Expression) : Expression() {\n override fun interpret() = left.interpret() - right.interpret()\n}\n\n// 解析器(简化版)\nfun parse(tokens: List<String>): Expression {\n val stack = mutableListOf<Expression>()\n var i = 0\n while (i < tokens.size) {\n when (tokens[i]) {\n "+" -> {\n val right = Number(tokens[++i].toInt())\n val left = stack.removeLast()\n stack.add(Add(left, right))\n }\n "-" -> {\n val right = Number(tokens[++i].toInt())\n val left = stack.removeLast()\n stack.add(Subtract(left, right))\n }\n else -> stack.add(Number(tokens[i]