0603.混入特徵(Mix-in Trait)

Mix-in Trait
所有人都有義務考慮自己的性格特徵。且必須合理控制這些特徵,而不去質疑他人的性格特徵是否更適合自己。—西塞羅

Trait: 特質 / 特徵 / 特性 / 特色 / 特點

在 Java 裡, 我們使用 介面(Interface)來達到特徵, 用以限定設計規範與多型. 在 Scala 與之相對的則是 Trait, 但比 Interface 還來的強大。


從 JAVA 到 SCALA 的設計論


對比在 Java 的中, 繼承規則被限定為"單一繼承", Java 為了解除這個限制而增設了介面(Interface), 來解封其單一繼承的限制魔咒; interface 最大的優點是它能做到對開發者在開發一個新的 API 時, 能對其應有的內容做一個合適"規範", 但很不幸的這 interface 有幾點存在的弊病 ...
  1. 可重用性(reusable) code 能力不足
    1. interface 僅能定義 抽象方法(abstract methods)與定義靜態常數值, 它滿足不了當遇到需要許多相同方法(包含內部實作相同的code)在不同 class 時, 這情況僅能利用傳統的手工複製與貼上功能, 最終其結果仍產生許多重複 code 分佈在被實作的 class 之中. 
  2. 經常性發生使用 interface 時, 必須額外連帶實作其不太相干的抽象方法.
  3. 持有狀態(State)的問題


Scala 設計構想


為此 Scala 提出更佳的解決設計, 使用了關鍵字 trait, 但與 Java 的 interface 並不完全相同 ..., Scala 開發者更喜好用 「組合」而不是繼承,因為組合一個 trait 和多重繼承有著很大的不同。它賦與了 Scala 在混入组合(mix-in composition)中的機制.
  1. 可作為設計規範或共同特性的實作
  2. 為 class 因單一繼承的限制, 實作類似多重繼承的概性
  3. 視為服務於單一目的功能模組的模組化之中, mix-in trait 也可稱為混入模組來實作 AP 的功能要求
  4. 做為 Code Template
  5. 可堆疊性的修飾




trait 特性


  1. 可以定義屬性和抽像方法, 也可是俱體的方法實作
  2. 功能模組概念
    1. trait 的關鍵字作用, 在創造一個的可復用類別, trait 封裝其相聚力強的方法和狀態(欄位)資料.
    2. trait 預設的 super class 為 AnyRef.
    3. trait 與 class 最大不同處為, 不可擁有建構引數(Parameters)
      1. trait 無法被實例化
      2. Trait 不能有任何一個類別類型的參數,也就是說,它的構造函數中不能有類類型的參數傳遞給它。
  3. trait 可以繼承自 class, 當然也可以承自其它 trait.
    1. 一個 trait 被定義,即可撰寫 extends 關鍵字將其"組合"入一個類中。多數則使用 with
    2. 一個 class 可同時俱備 N 個 trait class. (使用關鍵字 with)
    3. 可在實例化時, 才將 trait 混入
  4. classes 的 Super-class 是靜態綁定的,在 Trait 中是動態綁定的。




Example



trait Ord {
def < (that: Any): Boolean
def <=(that: Any): Boolean = (this < that) || (this == that)
def > (that: Any): Boolean = !(this <= that)
def >=(that: Any): Boolean = !(this < that)
}


scala> class WisdomFish  
defined class WisdomFish

scala> trait TWater extends WisdomFish {
     | def fire
     | }
defined trait TWater

scala> abstract class WisdomFish02 extends WisdomFish with TWater
defined class WisdomFish02

實例化時 mix-in
scala> val fish = new Wisdomfish with TWater with TFire




Trait => AOP


Trait 因其本身帶來的優異性, 故在進行類似 Java AOP 的開發是很棒的替代物.






widening thin interfaces to rich ones


橫軋寬展精簡型介面到富介面 / 擴寬瘦接口到胖接口


Comments