Scala 考虑行为的首选方式是什么

Scala 考虑行为的首选方式是什么,scala,coding-style,refactoring,Scala,Coding Style,Refactoring,假设我有几个类在内部共享一些行为,比如 def workspace = Plugin.get.reallyGet.getWorkspace 最好的解决办法是什么?我认为有两种可能性可以在使用代码中等效使用 trait WorkspaceProvider { def workspace = Plugin.get.reallyGet.getWorkspace } 把它混在一起,或者 object WorkspaceProvider { def workspace = Plugin.get

假设我有几个类在内部共享一些行为,比如

def workspace = Plugin.get.reallyGet.getWorkspace
最好的解决办法是什么?我认为有两种可能性可以在使用代码中等效使用

trait WorkspaceProvider {
  def workspace = Plugin.get.reallyGet.getWorkspace
}
把它混在一起,或者

object WorkspaceProvider {
  def workspace = Plugin.get.reallyGet.getWorkspace
}

然后导入它。你喜欢什么?为什么?

前者更可取。后者本质上是静态的、不可模仿的、难以测试的

由于您考虑的是耦合(这是一件非常好的事情),因此您应该熟悉蛋糕模式(“网络”对此有很多介绍,从最初描述概念的开始就开始了)。

您可以定义这两种模式:

trait WorkspaceProvider {
  def workspace = Plugin.get.reallyGet.getWorkspace
}

object WorkspaceProvider extends WorkspaceProvider
第一种形式更灵活。例如,它允许在实例化时混合:

trait Foo { this:WorkspaceProvider =>
   def bar = workspace.doSomethingRelevantHere
}

val myFoo = new Foo with WorkspaceProvider
但是,如果您只想使用
workspace
方法,则第二种形式更方便。例如在测试、原型等方面

编辑:


有关此方法的更多详细信息,请查看,其中Bill Venners展示了它是如何在ScalaTest中实现的。

我还推荐Daniel的这篇文章和这段视频Spiewak@SergeyPassichenko说得好。@RandallSchulz蛋糕模式很好,但它很重。存在类型ftw文章的url不再有效,因为precog站点不再有效。但作者非常友好地向我提供了这个存档版本:我检查了链接。其中一个问题似乎是名字冲突,这也是我最初想到的事情之一。从提供方来说,提供这两种选择似乎是一个不错的决定。