This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Chain of handler via Trait or via Classes?

No replies
mailleux
Joined: 2008-08-23,
User offline. Last seen 4 years 7 weeks ago.
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

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland