我想知道使用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] = ...
}
答案 0 :(得分:0)
一般来说,你应该使用对象单例来表示应用程序全局常量(如枚举)或状态变量等内容。
Traits是多重继承的另一种方法,它允许您在不定义层次结构的情况下跨类型共享功能(回答您的问题,您实际上并不创建特征实例)。 IIRC,在scala中,def是一个方法声明,val是一个不可变的常量。
答案 1 :(得分:0)
AppClient2 #cute会丢弃Server2的实例,但每次调用“DataA(输入)”或“DataB(输入)”时都会创建实例。 创建实例时将评估“val”,并在调用函数时评估“def”。 因此,如果将池称为“val”,则在每次调用DataX(输入)时都会创建5个线程。(但丢弃)
因为DataC是单例,“DataC.getC(输入)”不会创建两次线程池。