MST

星途 面试题库

面试题:Kotlin中设计模式的混合使用及场景分析

假设要开发一个电商购物车系统,涉及商品添加、删除、结算等功能,在Kotlin中结合至少三种设计模式(如观察者模式、单例模式、策略模式等)来设计和实现这个系统,并详细分析每种设计模式在该场景中的作用和优势。
31.9万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试

1. 单例模式

  • 作用:在电商购物车系统中,购物车本身通常是一个全局唯一的对象,整个应用程序应该只有一个购物车实例。使用单例模式可以确保这一点,使得不同模块都能访问到同一个购物车实例,避免了创建多个购物车实例导致数据不一致的问题。
  • 优势:节省系统资源,因为只创建一个实例。同时,便于管理购物车状态,不同部分的代码可以直接获取这个唯一实例进行操作。
  • 实现示例
object ShoppingCart {
    private val items = mutableListOf<Product>()

    fun addProduct(product: Product) {
        items.add(product)
    }

    fun removeProduct(product: Product) {
        items.remove(product)
    }

    fun calculateTotal(): Double {
        return items.sumOf { it.price }
    }
}

2. 观察者模式

  • 作用:当购物车中的商品发生变化(添加或删除商品)时,需要通知相关的模块,比如更新购物车总价显示、库存管理模块等。观察者模式可以实现这种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象状态发生变化时,自动通知所有观察者对象。
  • 优势:解耦了主题(购物车)和观察者(如总价显示模块、库存管理模块),使得它们可以独立变化。购物车不需要知道具体有哪些模块依赖它的状态变化,只需要在状态改变时通知观察者即可。这样系统的扩展性更好,新增或移除观察者都不会影响购物车的核心逻辑。
  • 实现示例
interface CartObserver {
    fun update()
}

class TotalPriceObserver : CartObserver {
    override fun update() {
        println("Total price updated: ${ShoppingCart.calculateTotal()}")
    }
}

class InventoryObserver : CartObserver {
    override fun update() {
        println("Inventory needs to be updated based on cart changes")
    }
}

class ShoppingCartSubject {
    private val observers = mutableListOf<CartObserver>()

    fun attach(observer: CartObserver) {
        observers.add(observer)
    }

    fun detach(observer: CartObserver) {
        observers.remove(observer)
    }

    fun notifyObservers() {
        observers.forEach { it.update() }
    }

    fun addProduct(product: Product) {
        ShoppingCart.addProduct(product)
        notifyObservers()
    }

    fun removeProduct(product: Product) {
        ShoppingCart.removeProduct(product)
        notifyObservers()
    }
}

3. 策略模式

  • 作用:在结算功能中,可能存在多种结算策略,比如普通结算、会员折扣结算、促销活动结算等。策略模式可以将这些不同的结算算法封装成独立的策略类,使得结算方式可以在运行时动态切换。
  • 优势:提高了代码的可维护性和可扩展性。如果需要新增一种结算策略,只需要创建一个新的策略类实现相应的接口,而不需要修改现有代码。同时,也使得结算功能的代码更加清晰,不同的结算逻辑被分离到不同的策略类中。
  • 实现示例
interface CheckoutStrategy {
    fun checkout(cart: ShoppingCart): Double
}

class NormalCheckoutStrategy : CheckoutStrategy {
    override fun checkout(cart: ShoppingCart): Double {
        return cart.calculateTotal()
    }
}

class MemberDiscountCheckoutStrategy : CheckoutStrategy {
    override fun checkout(cart: ShoppingCart): Double {
        val total = cart.calculateTotal()
        return total * 0.9 // 10% discount for members
    }
}

class ShoppingCart {
    // existing code...

    fun checkout(strategy: CheckoutStrategy): Double {
        return strategy.checkout(this)
    }
}

系统整合与使用示例

fun main() {
    val cartSubject = ShoppingCartSubject()
    val totalPriceObserver = TotalPriceObserver()
    val inventoryObserver = InventoryObserver()
    cartSubject.attach(totalPriceObserver)
    cartSubject.attach(inventoryObserver)

    val product1 = Product("Product 1", 10.0)
    cartSubject.addProduct(product1)

    val normalStrategy = NormalCheckoutStrategy()
    val memberStrategy = MemberDiscountCheckoutStrategy()

    val normalTotal = ShoppingCart.checkout(normalStrategy)
    val memberTotal = ShoppingCart.checkout(memberStrategy)

    println("Normal checkout total: $normalTotal")
    println("Member checkout total: $memberTotal")
}

data class Product(val name: String, val price: Double)

通过结合这三种设计模式,电商购物车系统在代码结构、可维护性、可扩展性等方面都得到了显著提升。