当前位置: 首页 > news >正文

面试复习题--kotlin的设计模式

Kotlin 以其简洁、安全、函数式特性,极大地改变了设计模式的实现方式。相比 Java,Kotlin 能以更少的代码实现相同的设计模式,甚至让某些模式变得“过时”或“内置”。

以下是针对 Kotlin 语言特性优化后的设计模式面试题,涵盖 常见模式、Kotlin 实现、对比 Java、高级技巧


一、Kotlin 特性如何影响设计模式?

Kotlin 特性对设计模式的影响
数据类 data class替代 BuilderValue Object 模式
单例 object内置线程安全单例,替代 Double-Checked Locking
密封类 sealed class完美实现状态机、策略模式,替代枚举或复杂继承
扩展函数 extension function实现装饰器、适配器更简洁
高阶函数 & Lambda替代策略、命令、观察者等行为模式
委托 by 关键字内置代理模式
空安全 ?减少 Null Object 模式的使用
作用域函数 letapplyrunalso简化构建、配置逻辑

二、高频 Kotlin 设计模式面试题

1. 如何在 Kotlin 中实现单例模式?有哪些方式?推荐哪种?

方式一:object(推荐 ✅)

kotlin

深色版本

object DatabaseManager {fun connect() = println("Connected")
}
// 使用
DatabaseManager.connect()
  • ✅ 线程安全
  • ✅ 懒加载(首次访问时初始化)
  • ✅ 代码最简洁
  • ✅ 防止反射攻击(Kotlin 1.4+)
方式二:object + @JvmStatic(用于 Java 互操作)

kotlin

深色版本

object Logger {@JvmStaticfun log(msg: String) { ... }
}
方式三:静态内部类(Java 风格,不推荐 ❌)

kotlin

深色版本

class Preferences private constructor() {companion object {val instance by lazy { Preferences() }}
}

结论优先使用 object,它是 Kotlin 的“一等公民”。


2. 如何用 Kotlin 实现 Builder 模式?能否优化?

传统 Java Builder

java

深色版本

User user = new User.Builder().name("Alice").age(25).build();

Kotlin 优化方案

方案一:使用 默认参数 + 命名参数

kotlin

深色版本

data class User(val name: String,val age: Int = 0,val email: String? = null
)// 使用
val user = User(name = "Alice", age = 25)
  • ✅ 最简洁
  • ✅ 编译期安全
  • ❌ 不适合大量可选参数(可读性下降)
方案二:使用 DSL 风格 Builder

kotlin

深色版本

class UserBuilder {var name: String = ""var age: Int = 0var email: String? = nullfun build() = User(name, age, email)
}fun user(init: UserBuilder.() -> Unit): User {return UserBuilder().apply(init).build()
}// 使用(DSL 风格)
val user = user {name = "Alice"age = 25email = "alice@example.com"
}
  • ✅ 可读性强,适合复杂对象
  • ✅ 类型安全

结论优先用默认参数,复杂场景用 DSL Builder


3. 如何用 Kotlin 实现策略模式?比 Java 好在哪?

Java 实现

java

深色版本

interface Strategy { void execute(); }
class ConcreteStrategyA implements Strategy { ... }
class Context {private Strategy strategy;void setStrategy(Strategy s) { this.strategy = s; }
}

Kotlin 实现

方案一:使用 高阶函数(推荐 ✅)

kotlin

深色版本

class PaymentProcessor {private var strategy: (amount: Double) -> Boolean = { false }fun setStrategy(strategy: (Double) -> Boolean) {this.strategy = strategy}fun process(amount: Double) = strategy(amount)
}// 使用
val processor = PaymentProcessor()
processor.setStrategy { amount ->println("Paying $amount via Credit Card")true
}
processor.process(100.0)
方案二:使用 密封类 + when

kotlin

深色版本

sealed class PaymentStrategy {object CreditCard : PaymentStrategy()object PayPal : PaymentStrategy()
}fun processPayment(strategy: PaymentStrategy, amount: Double) {when (strategy) {PaymentStrategy.CreditCard -> println("Credit Card: $amount")PaymentStrategy.PayPal -> println("PayPal: $amount")}
}

优势

  • ✅ 代码更短,无需定义接口/类
  • ✅ 运行时性能更好(无对象创建)
  • ✅ 支持 lambda 捕获上下文

4. 如何用 Kotlin 实现观察者模式?

Java 实现:接口 + 列表维护观察者。

Kotlin 优化方案

方案一:使用 高阶函数 + MutableList

kotlin

深色版本

class DataStore {private val observers = mutableListOf<(String) -> Unit>()fun addObserver(observer: (String) -> Unit) {observers.add(observer)}fun notify(data: String) {observers.forEach { it(data) }}
}// 使用
val store = DataStore()
store.addObserver { println("Observer 1: $it") }
store.notify("Hello")
方案二:使用 Flow(推荐 ✅)

kotlin

深色版本

class DataStore {private val _data = MutableSharedFlow<String>()val data: Flow<String> = _data.asSharedFlow()suspend fun update(data: String) {_data.emit(data)}
}// 使用
store.data.collect { println(it) }
  • ✅ 内置背压、线程切换、错误处理
  • ✅ 支持 debouncedistinctUntilChanged 等操作符
  • ✅ 协程集成

结论现代 Kotlin 项目推荐用 Flow 替代传统观察者模式


5. 如何用 Kotlin 实现装饰器模式?

Java 实现:继承或组合 + 接口。

Kotlin 优化方案

方案一:使用 扩展函数(推荐 ✅)

kotlin

深色版本

interface Notifier {fun send(message: String)
}class EmailNotifier : Notifier {override fun send(message: String) {println("Email: $message")}
}// 装饰:添加 SMS
fun Notifier.withSMS(): Notifier = object : Notifier by this {override fun send(message: String) {this@withSMS.send(message) // 调用原方法println("SMS: $message")   // 新功能}
}// 使用
val notifier = EmailNotifier().withSMS()
notifier.send("Hello") // Email + SMS
方案二:使用 委托 by

kotlin

深色版本

class SMSDecorator(private val notifier: Notifier) : Notifier by notifier {override fun send(message: String) {notifier.send(message)println("SMS: $message")}
}

优势:Kotlin 的 by 和扩展函数让装饰器模式实现更简洁、类型安全


6. 如何用 Kotlin 实现状态模式?

Java 实现:多态 + 状态类。

Kotlin 优化方案密封类 + when

kotlin

深色版本

sealed class UiState {object Loading : UiState()data class Success(val data: List<String>) : UiState()data class Error(val message: String) : UiState()
}fun render(state: UiState) {when (state) {UiState.Loading -> showLoading()is UiState.Success -> showData(state.data)is UiState.Error -> showError(state.message)}
}
  • ✅ 编译期 exhaustive check(when 必须覆盖所有情况)
  • ✅ 数据封装安全
  • ✅ 比继承树更清晰

结论密封类是 Kotlin 实现状态模式的最佳方式


7. Kotlin 中哪些设计模式变得“过时”了?

模式为什么“过时”Kotlin 替代方案
Builder 模式数据类 + 默认参数更简洁data class + 命名参数
Singletonobject 更安全简洁object
Factory Methodcompanion object + when 更直接companion object create()
Null Object空安全 ? 减少空指针类型系统本身
Visitor密封类 + when 更安全sealed class + when

三、高级面试题(结合协程、DSL)

1. 如何用 Kotlin 实现一个 DSL(领域特定语言)?

kotlin

深色版本

// 实现一个简单的 HTML DSL
fun html(init: HTML.() -> Unit): HTML {val html = HTML()html.init()return html
}class HTML {val body = Body()fun body(init: Body.() -> Unit) = body.init()
}class Body {val divs = mutableListOf<Div>()fun div(init: Div.() -> Unit) {divs += Div().apply(init)}
}class Div {var text: String = ""
}// 使用(像 HTML 一样写 Kotlin)
val result = html {body {div {text = "Hello"}}
}

应用场景:Gradle Kotlin DSL、Anko(已弃用)、Ktor 路由。


2. 如何用 Flow 实现发布-订阅模式?

kotlin

深色版本

class EventBus {private val _events = MutableSharedFlow<Event>()val events: Flow<Event> = _events.asSharedFlow()suspend fun post(event: Event) {_events.emit(event)}
}// 使用
eventBus.events.onEach { handleEvent(it) }.launchIn(scope)
  • ✅ 支持背压
  • ✅ 线程切换(flowOn
  • ✅ 操作符丰富(filterdebounce

四、总结:Kotlin 设计模式面试要点

模式Kotlin 最佳实践
Singletonobject
Builderdata class + 默认参数 或 DSL
Strategy高阶函数 (T) -> R
ObserverFlow / SharedFlow
Statesealed class + when
Decorator扩展函数 或 by 委托
Factorycompanion object + when
Adapter扩展函数直接转换

💡 核心思想用语言特性简化模式,而不是用模式模拟语言特性

掌握这些 Kotlin 特有的实现方式,能让你在面试中脱颖而出,展现对语言深度的理解。

http://www.dtcms.com/a/365827.html

相关文章:

  • shell内置命令
  • UART更好的封装 添加容错代码
  • Qt6用Chart模块做数据可视化?别再用老套路,看看这套35张图背后的秘密
  • [密码学实战](GBT 15843.2-2017)Java实现基于SM4的实体鉴别机制(四十八)
  • MinIO祭了,RustFS来了!
  • 关于node中的一些用到的读取文件方法
  • Dubbo3单端口多协议源码分析
  • 员工拍照泄密?U盘偷拷资料?终端数据安全如何守护?
  • G1垃圾收集器
  • 【高级】系统架构师 | 信息系统战略规划、EAI 与新技术
  • 攻防世界secret-galaxy-300
  • 深度学习----卷积神经网络的数据增强
  • 如何给JavaScript语句添加注释?
  • 19.JS
  • Jmeter怎么实现接口关联?
  • 算法题(198):数字三角形
  • 使用 Terraform、AWS 和 Python 构建无服务器实时数据管道
  • 学习React-9-useSyncExternalStore
  • Ubuntu下把 SD 卡格式化为 FAT32
  • 【工具变量】“国家级大数据综合试验区”试点城市DID(2000-2024年)
  • ArkTS状态管理V1
  • Llama v3 中的低秩自适应 (LoRA)
  • 头歌实训作业答案C++ 01
  • Proteus8 + STM32CubeMX 实现 STM32F103R6 串口通信教程
  • JMeter下载安装及使用入门
  • 常用符号 Emoji 对照表——Unicode UTF-8
  • SQLSERVER临时表
  • 关于专业化与多元化该怎么选?
  • 解决MQ访问不了或者登录不成功问题
  • 卷积神经网络CNN-part2-简单的CNN