La aplicación de ejemplo de girasol de Google utiliza una clase privada con un objeto complementario para implementar un patrón Singleton de su repositorio en lugar de simplemente implementar el repositorio como un objeto (inherentemente Singleton).
Esta es la primera vez que veo un Singleton implementado de esta manera en Kotlin en lugar de implementarlo como un Objeto. ¿En qué contexto(s) debería usarse esta implementación de constructor privado en lugar de la implementación de Objeto más común?
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 } } } }El uso de un object es un problema si su instancia de singleton necesita parámetros, como en este caso aquí, con GardenPlantingDao , ya que no pueden tomar argumentos de constructor. Esto surge con frecuencia en Android, ya que hay muchos casos en los que singletons requiere un Context para funcionar.
Todavía podría usar un object en estos casos, pero sería inseguro o inconveniente:
De ahí la forma "tradicional" de implementar un singleton con un constructor privado y un método de fábrica.