0602.單例(Singleton)物件模組

Singleton(object | module)

Scala 相較於 JAVA 是個純 OO 的程序語言, 它完全不使用 靜態(static) 空間, 當然也就無 static 所引發的缺陷與破壞 OO 結構的問題, Scala 的 object 宣告, 簡單來說, 就像是個 Java 的 static 的替代品, 但更加符合對單例樣式的要求 - WisdomFish.ORG


單例樣式(Singleton Pattern)


僅能有一個實例的類別程序, 它描繪的物件扮演著整體服務中心焦點的角色, 執行諸如對 DB 的存取, 物件工廠等等的操作.
  • 單例無法進行初始化過程, 故不能對其建構子傳遞參數
    • class 和單例 object 間的一個差別是,單例 object 不可帶有參數,而 class 可以。因為你不能用 new 關鍵字實例化一個單例 object,你沒機會傳遞給它參數。
  • Scala 對於單例模式的處理, 又將之稱為 定義模組(defined module)
  • Scala 用 Companion object 來替代 Java 中 static 的需求


object


object 是 Scala 的關鍵保留字, 最大的用意在創造 單例(Singleton)模式 物件的效果. 對一位完全新手的程序語言學習者來說, 你可以暫時先把 object 的宣告視為, 產生一個物件但不需要每次都要使用 new 字眼, 才能創造能活在 RAM 中物件.
  • 靜態方法例如 main( ) 的執行都是化為 scala.tools.nsc.MainGenericRunner (scala-complier.jar) 中的 main( ) 來進行.
  • Scala 在宣告一個建構案例時, 冠以 object 來達到單例物件的效果, 內容當然可同 class 一樣包含欄位與方法宣告,
object Hello { ... }
  1. 其內容可加上 main 方法, 來構築可被當成程式進入點的實例(Instance)
scala> object WisdomFsihObject { }
defined module WisdomFsihObject




伴生物件(Companion object)


伴生 / 共生 / 夥伴 / 同伴
為了能讓同一個類別名稱的 API 能像 Java 般同時內置靜態與非靜態方法, Scala 逐提出 Companion object 的設計, 創建一個可以與 class 產生關聯的 object, 與 class 共享同樣的名字, 例如 Actor 就是一個 Actor class 的伴生物件.
  • class 與 Companion object 間不存有界限, 可以相互取存 private 的欄位與方法
  • 通常將 class 與 Companion ojbect 寫在同一份文件中, 每個 class 都可以有 Companion class
  • 將 class 標記為 private 來防止被建構實例, 但 Companion object 仍可取存它與實例化 class
scala> class WisdomFish private(kuo: Int) { }
defined class WisdomFish

scala> val fish = new WisdomFish(1)
<console>:6: error: constructor WisdomFish cannot be accessed in object $iw
       val fish = new WisdomFish(1)
                  ^


apply( )

scala 語法蜜糖, 讓 object 能在外觀上像 class 一樣看似能用參數傳遞給建構子,
scala> class WisdomFish private (val fish: Int)
defined class WisdomFish

scala> object WisdomFish { def apply(fish: Int) = 1 }
defined module WisdomFish

scala> WisdomFish(3)
res2: Int = 1

scala> new WisdomFish(3)
<console>:7: error: constructor WisdomFish cannot be accessed in object $iw
       new WisdomFish(3)
       ^




For Java Developer


在 JAVA 中, 我們使用 static 關鍵字來創造靜態類別與提供靜態成員來直接使用, JVM 中劃了一個專區來置放 static 程序專區, 但它們已非物件形態了, 嚴格來說 static 宣告破壞了物件導向, 而改以 程式區塊 的方式存在其欄位與方法成員.

在 scala 完全排除使用靜態觀點, 改以 Singleton Pattern 來創造單例物件, 簡單而言, 就是創造在 JVM 中可確保唯一的單一個物件實例(Instance), 這樣它仍是以物件的方式存在於 JVM, 又可以像 static 的宣告一樣被使用, 排除了 static 的缺陷.

再來, 思考單例物件的一種方式是把它當作是或許你在 Java 中寫過的任何靜態方法之家。可以在單例物件上用類似的語法調用方法:

單例物件名.方法名

然而單例物件不只是靜態方法的收容站。它同樣是個第一 class 的 object。因此你可以把單例 object 的名字看作是貼在object上的「名簽」



Example



class CatDemo {
def sound = Cat.sound
val sound2 = Cat.sound
}

object Cat {
val sound = "KaKa"
}




Scala API 文檔中的分類


在每個套件下被區分成二大類來查詢
  • Classes
  • Object



References


  • http://developer.51cto.com/art/200907/137993.htm
Comments