Reputation: 983
Let's say I have a couple of classes internally sharing some behavior like
def workspace = Plugin.get.reallyGet.getWorkspace
What is the best way to factor it out? I see two possibilities which can be used equivalently in the using code.
trait WorkspaceProvider {
def workspace = Plugin.get.reallyGet.getWorkspace
}
and mix it in or
object WorkspaceProvider {
def workspace = Plugin.get.reallyGet.getWorkspace
}
and import it. What would you prefer and why?
Upvotes: 2
Views: 132
Reputation: 40461
You can define both:
trait WorkspaceProvider {
def workspace = Plugin.get.reallyGet.getWorkspace
}
object WorkspaceProvider extends WorkspaceProvider
The first form is more flexible. For example, it allows to be mixed at instanciation:
trait Foo { this:WorkspaceProvider =>
def bar = workspace.doSomethingRelevantHere
}
val myFoo = new Foo with WorkspaceProvider
But the second form is more convenient if you just want to use the workspace
method. For example in tests, prototypes, etc.
EDIT:
For a little more elaboration about this approach, check out "Selfless Trait Pattern", where Bill Venners shows how it is implemented in ScalaTest.
Upvotes: 2
Reputation: 26486
The former is preferable. The latter is essentially static, un-mockable and hard to test.
Since you're thinking in terms of coupling (a very good thing) you should familiarize yourself with the Cake Pattern (it is much covered on 'Net, starting with the paper in which the concept was first described).
Upvotes: 4