簡體   English   中英

如何確定使用特征'''或類來“注入”?

[英]How to determine to use trait to 'with' or class to 'inject'?

在編寫scala代碼時,我很困惑地選擇一個traitclass

起初,我有一個控制器, with幾個特點:

class MyController extends Controller 
                   with TransactionSupport 
                   with JsonConverterSupport 
                   with LoggerSupport

在這些特性中,我定義了一些可以直接在MyController使用的方法和字段。

但我的朋友說:當你extendswith特質時,它應該be a特質。

看看MyController ,它是一個Controller ,但它不是一個TransactionSupport ,不是一個JsonConverterSupport ,不是一個LoggerSupport ,所以它不應該with它們一起使用。

所以代碼變成:

class MyController(tranSupport: TransactionSupport, 
                   jsonConverter: JsonConverterSupport, 
                   loggerSupport: LoggerSupport) extends Controller

但我對這段代碼感覺不太好,這看起來很奇怪。

我看到trait在scala代碼中大量使用,我什么時候應該使用它或者使用類來注入?

我會推薦你接口應該是形容詞 雖然一些特征可能扮演一個類的一部分(因此,是名詞並尊重“是一個”關系),但當用作mixin時,它們往往會扮演界面的一部分。

作為一個“形容詞”,該特征將為他們所擴展的任何內容添加一個合格的屬性。 例如,它們可能是ComparableSerializable

找到一個適合的形容詞可能有點難度 - 你會用什么形容詞來表示LoggerSupport - 所以不要覺得過分受到限制。 請注意,特質是完全錯誤的,因為它必然是一種“是一種”的關系。

不過,我會盡量避免使用特征來代替“has-a”關系。

我的意見是,它不一定to be它。 混合是一種與繼承不同的概念。 即使在語法上它是相同的,但它並不意味着相同。 混合的典型用例就像你寫的那樣記錄。 這並不意味着如果您的服務類混合了Logging特性, it is一個記錄器。 這只是如何將功能組合到工作對象中的另一種方式。

奧德斯基建議,如果你不確定,你可以使用trait因為它們更靈活。 如果需要,您可以在將來將trait更改為class

有時當我覺得混合特性看起來不好時,我會使用這樣的模塊模式:

trait JsonConverterModule {

    protected def jsonConverter: JsonConverter

    protected trait JsonConverter {
      def convert(in: Json): Json
    }
  }

class MyController extends Controller with JsonConverterModule {
   private doSmth = jsonConverter.convert(...)
}

在這種情況下,MyController看起來更像是一個Controller,所有與Json相關的東西都隱藏在MyController'client'中

你的第一個特征示例是“蛋糕模式”,第二個例子是“構造函數注入”。 兩者都是在Scala中進行依賴注入的完全有效的方法。 蛋糕模式功能強大,你可以注入類型成員,不同的特性可以很容易地相互通信(我們不必創建單獨的對象並將它們傳遞給每個其他對象,通常需要setter注入而不是簡單的構造函數注入),但是,必須在編譯時實現類型,並且必須為每個特征組合實現單獨的類。 構造函數注入允許您在運行時構建對象,並且可以針對大量組合進行更好的擴展。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM