簡體   English   中英

通過Scala中的Mixins管理依賴圖

[英]Managing dependency graph via mixins in scala

我有一個需要2個特征的類,兩個特征都需要相同的特征。 我要如何在這種情況下添加它

class RandomTest extends AbstractTestCase {
  "asdasd" should "asdsda" in {
    val a = new Application with XYZAppName with Session with MetricsPublisher

    a.a()
  }

  abstract class Application extends Session with MetricsPublisher {

    println("Application")
    def a() : Unit = { println("application.a")}
  }



  trait RequiredAppContext {
    println("RequiredAppContext")
    val appName : String
  }

  trait MetricsPublisher extends RequiredAppContext {
    this:RequiredAppContext =>
    println("MetricsPublisher")
  }
  trait Session extends RequiredAppContext{
    this:RequiredAppContext =>
    println("Session")
    lazy val appNameoverload = func(appName)
    def func(value:String ) {println("appNameoverload "+appName)}

  }


  // implmentations
  trait XYZAppName extends RequiredAppContext {
    println("XYZAppName")
    override val appName = "xyz"
  }
}

這是該程序的輸出:

 [scalatest] RequiredAppContext 
 [scalatest] Session 
 [scalatest] MetricsPublisher 
 [scalatest] Application 
 [scalatest] XYZAppName
 [scalatest] application.a

將XYZAppName初始化顯示在Session之前的最佳方法是什么?

Scala的線性化算法,管理特征圖初始化順序並解決菱形繼承問題,以聲明順序遍歷(非循環)繼承圖,滿足初始化父節點的要求,但忽略了已初始化的所有重復項。 這里的要點是要初始化某個類,您需要首先初始化其基類,以及擴展它的所有特征。 extendsnew extends之后,Scala甚至不允許在任何位置指定基類-您只能使用with來添加特征。 對於(匿名)類的a基類是Application

a.type
  -> Application
    -> Session
      -> RequiredAppContext
    -> MetricsPublisher
      -> RequiredAppContext // omitted
  -> XYZAppName
    -> RequiredAppContext  // omitted
  -> Session // omitted
    -> RequiredAppContext  // parent omitted
  -> MetricsPublisher // omitted
    -> RequiredAppContext  // parent omitted

所以你唯一的選擇是修改你的繼承層次,轉向Application到特質,並重新排序它XYZAppName在定義a

trait Application extends Session with MetricsPublisher
...
val a = new XYZAppName with Application with Session with MetricsPublisher
// RequiredAppContext
// XYZAppName
// Session
// MetricsPublisher
// Application

但是,該解決方案無法涵蓋所有​​可能的情況-如果您的抽象類具有構造函數,則無法將其轉換為特征( 正在做的工作是在以后的Scala版本中允許特征參數,但距離完成還很遙遠)。 如果基類是在外部代碼中定義的,這也不是一個選擇。

暫無
暫無

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

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