Kotlin中的單例模式

szy1981 7年前發布 | 15K 次閱讀 Kotlin 單例模式

在編程中,我們都應該接觸到設計模式,無論是從時間總結,亦或者是從書上習得后嘗試使用。這其中單例模式,是我們編程過程中很常見,也很簡單的一種設計模式。我曾經寫過一篇比較通用的關于該模式的文章,即單例這種設計模式。

目前,隨著Google欽定Kotlin為Android 開發官方語言,Kotlin的學習熱潮也應聲而起。本文嘗試講解單例模式在Kotlin的具體實現和應用。希望能夠對大家學習使用Kotlin有所幫助。

超簡版單例

Kotlin引入了一個叫做object的類型,用來很容易的實現單例模式。如下面的代碼

object SimpleSington {
  fun test() {}
}
//在Kotlin里調用
SimpleSington.test()

//在Java中調用
SimpleSington.INSTANCE.test();

這個版本的實現,其實是個語法糖(Kotlin漫山遍野都是語法糖)。其真正的實現類似于這樣

public final class SimpleSington {
   public static final SimpleSington INSTANCE;

   private SimpleSington() {
      INSTANCE = (SimpleSington)this;
   }

   static {
      new SimpleSington();
   }
}

因而Kotlin這個超簡版單例實現省去了

  • 顯式聲明靜態instance變量
  • 將構造函數private化處理

關于調用時注意

這段單例代碼在Kotlin中使用很簡單,即

SimpleSington.test()

但是在Java和Kotlin混編時,Java代碼中調用則需要注意,使用如下

SimpleSington.INSTANCE.test();

其實在Kotlin中調用單例本質上還是涉及到了INSTANCE這個變量,只是為了簡化,隱藏了一些細節。

object類型的單例模式,本質上是餓漢式加載,即在類加載的時候創建單例。它可能存在的問題有

  • 如果構造方法中存在過多的處理,會導致加載這個類時比較慢,可能引起性能問題。
  • 如果使用餓漢式的話,只進行了類的裝載,并沒有實質的調用,會造成資源的浪費。

懶漢式加載

針對餓漢式的潛在問題,我們可以使用懶漢式來解決,即將實例初始化放在開始使用之前。Kotlin版的懶漢式加載代碼如下

class LazySingleton private constructor(){
    companion object {
        val instance: LazySingleton by lazy { LazySingleton() }
    }
}
  • 顯式聲明構造方法為private
  • companion object用來在class內部聲明一個對象
  • LazySingleton的實例instance 通過lazy來實現懶漢式加載
  • lazy默認情況下是線程安全的,這就可以避免多個線程同時訪問生成多個實例的問題

該用哪個版本

關于如何選擇餓漢式還是懶漢式,通常應該從兩方面考慮

  • 實例初始化的性能和資源占用
  • 編寫的效率和簡潔

對于實例初始化花費時間較少,并且內存占用較低的話,應該使用object形式的餓漢式加載。否則使用懶漢式。

關于單例的更多知識和問題,請參考閱讀單例這種設計模式

 

來自:http://droidyue.com/blog/2017/07/17/singleton-in-kotlin/

 

 本文由用戶 szy1981 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!