David Apltauer
David Apltauer

Reputation: 983

What is the prefered way to factor out behavior

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

Answers (2)

paradigmatic
paradigmatic

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

Randall Schulz
Randall Schulz

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

Related Questions