Scala:使用单身人士与特质/等级

时间:2015-05-08 22:33:11

标签: scala singleton state mixins traits

我想知道使用mixins和singletons的含义。正如我们大多数人所认同的那样,单身人士是邪恶的,因为他们维持着国家,很难跟踪这种状态。特质是优越的,因为它们可以混合,容易嘲笑等等。但我想知道幕后发生的事情的实际含义:如何使用mixins不会导致问题?

以下代码示例仅用于演示我的问题。

方法#1:全身使用单身人士:

object Server {
  def fetchData(input: Input): String = ...
}
object Servers { 
  val inMemoryServers: Seq[Server] = ...
  def randInMemServer = Random.shuffle(Servers.inMemoryServers).head
}
object AppClient {
  def execute(input: Input) = {
    Servers.randInMemServer.fetchData(input)
  }
}

方法#2:使用mixins

trait Server2 {
  def fetchData(input: Input): String = ...
}
trait Servers2 extends Server2 { 
  val inMemoryServers: Seq[Server] = ...
  val httpServers: Seq[Server] = ...
}
case class DataA(input: Input) extends Servers2 {
  def getA = inMemoryServers
}
case class DataB(input: Input) extends Servers2 {
  def getB = ...
}
object DataC extends Servers2 {
  def getC(input: Input) = ...
}
object AppClient2 {
  def execute(input: Input) = {
    val a = DataA(input).getA // line 1
    val b = DataB(input).getB // line 2
    val c = DataC.getC(input) // line 3
  }
}

第3行之后在AppClient中创建了多少个Server2和Servers2实例?

假设Server2有一个变量来创建一个线程池(比如5个线程,见下文),在(第3行)之后创建了多少个?

trait Server2 {
  val pool: Threadpool = ... // create a pool of 5 threads
  def fetchData(input: Input): String = ...
}

如果Server2将成员声明为def而不是val,如果如下所示,会产生什么影响?是否在第1行,第2行和第3行中创建了新的线程池?

trait Servers3 extends Server2 { 
  def threadPool: Threadpool = ...
  def inMemoryServers: Seq[Server] = ...
}   

2 个答案:

答案 0 :(得分:0)

一般来说,你应该使用对象单例来表示应用程序全局常量(如枚举)或状态变量等内容。

Traits是多重继承的另一种方法,它允许您在不定义层次结构的情况下跨类型共享功能(回答您的问题,您实际上并不创建特征实例)。 IIRC,在scala中,def是一个方法声明,val是一个不可变的常量。

答案 1 :(得分:0)

AppClient2 #cute会丢弃Server2的实例,但每次调用“DataA(输入)”或“DataB(输入)”时都会创建实例。 创建实例时将评估“val”,并在调用函数时评估“def”。 因此,如果将池称为“val”,则在每次调用DataX(输入)时都会创建5个线程。(但丢弃)

因为DataC是单例,“DataC.getC(输入)”不会创建两次线程池。