gpt4 book ai didi

Kotlin 单例 : Object vs a Class with private constructor

转载 作者:行者123 更新时间:2023-12-02 12:47:23 29 4
gpt4 key购买 nike

sunflower example app by Google使用带有伴随对象的私有(private)类来实现其存储库的单例模式,而不是简单地将存储库实现为(固有的单例)对象。

这是我第一次看到在 Kotlin 中以这种方式实现单例,而不是将其作为对象实现。在什么情况下应该使用这个私有(private)构造函数实现而不是更常见的 Object 实现?

class GardenPlantingRepository private constructor(
private val gardenPlantingDao: GardenPlantingDao
) {
suspend fun createGardenPlanting(plantId: String) {
withContext(IO) {
val gardenPlanting = GardenPlanting(plantId)
gardenPlantingDao.insertGardenPlanting(gardenPlanting)
}
}

suspend fun removeGardenPlanting(gardenPlanting: GardenPlanting) {
withContext(IO) {
gardenPlantingDao.deleteGardenPlanting(gardenPlanting)
}
}

fun getGardenPlantingForPlant(plantId: String) =

gardenPlantingDao.getGardenPlantingForPlant(plantId)

fun getGardenPlantings() = gardenPlantingDao.getGardenPlantings()

fun getPlantAndGardenPlantings() = gardenPlantingDao.getPlantAndGardenPlantings()

companion object {
// For Singleton instantiation
@Volatile private var instance: GardenPlantingRepository? = null

fun getInstance(gardenPlantingDao: GardenPlantingDao) =
instance ?: synchronized(this) {
instance ?: GardenPlantingRepository(gardenPlantingDao).also { instance = it }
}
}
}

最佳答案

使用 object如果您的单例实例需要参数,就像在这种情况下,使用 GardenPlantingDao 是一个问题,因为它们不能接受构造函数参数。这在 Android 上经常出现,因为在很多情况下单例需要 Context操作。

您仍然可以使用 object在这些情况下,但它要么不安全,要么不方便:

  • 第一个选项是在使用任何其他方法之前使用 setter 方法为其提供依赖项。这意味着所有其他方法都必须检查依赖项是否已初始化,并且可能会在没有初始化的情况下抛出异常,这会导致运行时问题。
  • 或者,您可以要求任何依赖项作为单例的每个方法的参数,这在调用站点很乏味。

  • 因此,使用私有(private)构造函数和工厂方法来实现单例的“传统”方式。

    关于Kotlin 单例 : Object vs a Class with private constructor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54489418/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com