- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Chain of handler via Trait or via Classes?
Wed, 2009-02-25, 16:02
I have implemented and actor which handled messages via a set of handlers. A large number of changes happen in the state depending of the messages and I wanted to isolate each part of the behavior in its own handler.
My original approach was:
val controller = new AbstractController() {
addHandler(new FirstHandler(args)) // where FirstHandler is a class that takes care of some parts of the update
addHandler(new SecondHandler(args))
}
When I process the events I do a:
for(h<-handles) h.doSomething(param)
This works ok, but as all things scala I was wondering if there is another way...
So I decided to try making the handlers traits. As in the code below.
package test
package CBT {
class Composed(val seed:Int) {
var names:List[String]=Nil
var doits:List[ ()=> Unit]=Nil
def add(name:String) {
names=names:::List(name)
}
def addDoit(doit: ()=>Unit) {
doits=doit::doits
}
def doit() {
println("Composed doit")
for(x<-doits) x()
}
}
trait Doit extends Composed {
def doit():Unit
}
trait First extends Doit {
this.add("First")
addDoit(()=> {
println("First doit "+seed)
})
}
trait Second extends Doit {
this.add("Second")
addDoit(()=> {
println("Second doit "+seed)
})
}
class MyComposed(seed:Int) extends Composed(seed) with First with Second
}
object ControlByTrait {
def main(args : Array[String]) : Unit = {
val me=new CBT.MyComposed(10)
println(me.names)
println(me.doits + "and I am " +me)
me.doit()
}
}
Now I have other alternatives with traits, such as having doit call the next in the chain (an not register to a list of handlers):
def doit() {
//do something
super.doit()
}
This works too and allows the chain to be broken mid way. However not calling the next chain may cause problem...
The advantage of building with traits is that a line like:
class MyComposed(seed:Int) extends Composed(seed) with First with Second
simplifies the constructor and kind of says it all on the implicit constructor code.
Any comments on which is the best approach?
Thomas
My original approach was:
val controller = new AbstractController() {
addHandler(new FirstHandler(args)) // where FirstHandler is a class that takes care of some parts of the update
addHandler(new SecondHandler(args))
}
When I process the events I do a:
for(h<-handles) h.doSomething(param)
This works ok, but as all things scala I was wondering if there is another way...
So I decided to try making the handlers traits. As in the code below.
package test
package CBT {
class Composed(val seed:Int) {
var names:List[String]=Nil
var doits:List[ ()=> Unit]=Nil
def add(name:String) {
names=names:::List(name)
}
def addDoit(doit: ()=>Unit) {
doits=doit::doits
}
def doit() {
println("Composed doit")
for(x<-doits) x()
}
}
trait Doit extends Composed {
def doit():Unit
}
trait First extends Doit {
this.add("First")
addDoit(()=> {
println("First doit "+seed)
})
}
trait Second extends Doit {
this.add("Second")
addDoit(()=> {
println("Second doit "+seed)
})
}
class MyComposed(seed:Int) extends Composed(seed) with First with Second
}
object ControlByTrait {
def main(args : Array[String]) : Unit = {
val me=new CBT.MyComposed(10)
println(me.names)
println(me.doits + "and I am " +me)
me.doit()
}
}
Now I have other alternatives with traits, such as having doit call the next in the chain (an not register to a list of handlers):
def doit() {
//do something
super.doit()
}
This works too and allows the chain to be broken mid way. However not calling the next chain may cause problem...
The advantage of building with traits is that a line like:
class MyComposed(seed:Int) extends Composed(seed) with First with Second
simplifies the constructor and kind of says it all on the implicit constructor code.
Any comments on which is the best approach?
Thomas