目录

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

面试复习题–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 {
    @JvmStatic
    fun 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 = 0
    var email: String? = null

    fun build() = User(name, age, email)
}

fun user(init: UserBuilder.() -> Unit): User {
    return UserBuilder().apply(init).build()
}

// 使用(DSL 风格)
val user = user {
    name = "Alice"
    age = 25
    email = "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 特有的实现方式,能让你在面试中脱颖而出,展现对语言深度的理解。