單例設(shè)計模式就不用多介紹了逐虚,說是大家最熟悉的設(shè)計模式也不為過泥彤,在Effective Java中有兩條與之相關(guān):第3條用私有構(gòu)造器或者枚舉類型強化 Singleton 屬性嫂粟,第4條通過私有構(gòu)造器強化不可實例化的能力踩衩。單例模式的關(guān)鍵在于保證多線程下仍然是單例柴罐,常見的做法有:
- 靜態(tài)變量存儲單例(餓漢模式)
- Double-checked locking
- 靜態(tài)類Holder
- 枚舉類
眾所周知徽缚,Kotlin使用object
關(guān)鍵字來實現(xiàn)單例,這種實現(xiàn)方式實際上是方式1餓漢模式革屠,并且僅適用于只有默認(rèn)構(gòu)造函數(shù)的類凿试,如果構(gòu)造函數(shù)包含有參數(shù),是不能使用object
關(guān)鍵字的似芝,此時還得使用方式2:
class PlantRepository private constructor(private val plantDao: PlantDao) {
fun getPlants() = plantDao.getPlants()
companion object {
@Volatile private var instance: PlantRepository? = null
fun getInstance(plantDao: PlantDao) =
instance ?: synchronized(this) {
instance ?: PlantRepository(plantDao).also { instance = it }
}
}
}
這就是Kotlin味道的Double-checked locking那婉,本質(zhì)上跟Java的寫法是一樣的,只是利用了?:
操作符以及also
擴展函數(shù)之后變得更加簡潔党瓮。至于為什么需要在instance
上加上注解@Volatile
(即Java的關(guān)鍵字volatile
)详炬,可以查看維基百科Double-checked locking。