前言
在Kotlin中,不像Java有靜態變量和靜態方法,那麼如何實現單例模式呢?在這片文章中將介紹在Kotlin中如何實現單例模式
單例模式
單例模式(Singleton Pattern)是最簡單的設計模式之一。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。
這種模式涉及到一個單一的類,該類負責創建自己的對象,同時確保只有單個對象被創建。這個類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實例化該類的對象。
注意:
- 1、單例類只能有一個實例。
- 2、單例類必須自己創建自己的唯一實例。
- 3、單例類必須給所有其他對象提供這一實例。
單例實現方法
在Kotlin中,沒有靜態變量和靜態方法,但是可以通過Kotlin中的 伴生對象 來實現(關於伴生對象可參考Kotlin學習筆記——對象表達式與對象聲明中關於伴生對象的相關介紹)。下面,我們用懶漢式的單例模式實現作爲示例:
- 懶漢式單例模式
fun main(args: Array<String>) {
Singleton.getInstance().code = 200
Singleton.getInstance().msg = "Success"
Singleton.getInstance().data = "Data"
Singleton.getInstance().print()
// 通過多次打印獲取到的單例,驗證都是同一個對象
println(Singleton.getInstance())
println(Singleton.getInstance())
println(Singleton.getInstance())
}
class Singleton private constructor(){
// 單例,私有的主構造函數,無從構造函數
var code: Int = 0
var msg: String = ""
var data: String = ""
// 聲明類的伴生對象
companion object {
private var singleInstance: Singleton? = null
get() {
// 懶漢模式
if(null == field) {
field = Singleton()
}
return field
}
@Synchronized // 添加註解,線程同步,線程安全
fun getInstance(): Singleton {
return singleInstance!! // 表示非空時執行
}
}
fun print() {
println("Result: $code, $msg, $data")
}
}
以上示例中,如果將伴生對象的屬性聲明爲開放,那麼
Singleton
類是可以忽略伴生對象名稱(以上示例伴生對象名稱省略掉)直接調用伴生對象的屬性,之所以在伴生對象內部增加了getInstance()
函數,是因爲 懶漢式 的單例模式,單例對象初始值是null
,在getInstance()
函數裏返回單例對象時增加一個非空斷言(!!
),這樣就無需再每個調用的地方都增加非空斷言。如果使用 餓漢式 的單例,可以完全不經過伴生對象內部的函數來中轉(只需要將伴生對象的單例對象聲明爲開放,當然,如果爲了保持隊形,你依舊可以在伴生對象中聲明個函數進行中轉)
- 餓漢式單例模式
fun main(args: Array<String>) {
Singleton.instance.code = 200
Singleton.instance.msg = "Success"
Singleton.instance.data = "Data"
Singleton.instance.print()
// 通過多次打印獲取到的單例,驗證都是同一個對象
println(Singleton.instance)
println(Singleton.instance)
println(Singleton.instance)
}
class Singleton private constructor(){
// 單例,私有的主構造函數,無從構造函數
var code: Int = 0
var msg: String = ""
var data: String = ""
companion object {
public var instance: Singleton = Singleton()
@Synchronized // 註解,get線程同步
get
}
fun print() {
println("Result: $code, $msg, $data")
}
}