2011-08-05 14 views
6

tengo el siguiente código:¿Es posible encadenar métodos de diferentes características?

class Parameterizable{ 
    var map: Map[String, String] = new scala.collection.immutable.HashMap() 
    def put(entry: Tuple2[String, String]) = { 
    map = map + entry; this 
    } 
} 

class Query() extends Parameterizable{ 
    override def toString = { 
    map.isEmpty match{ 
     case true => "" 
     case false => "?" + map.map{case (key, value) => key + "=" + value}.mkString("&") 
    } 
    } 
} 

trait PageParameter extends Parameterizable{ 
    def page(page: Int) = put(("page" -> page.toString)) 
    def pageSize(pageSize: Int) = put(("pagesize" -> pageSize.toString)) 
} 

trait DateParameter extends Parameterizable{ 
    def fromDate(date: java.util.Date) = put(("fromdate" -> (date.getTime()/1000L).toString())) 
    def toDate(date: java.util.Date) = put(("todate" -> (date.getTime()/1000L).toString())) 
} 
//and other similar traits 

me gustaría hacer algo como:

class ExtendedQuery extends Query with PageParameter with DateParameter 
val query = new ExtendedQuery 
query.page(4).pageSize(5).fromDate(new java.util.Date) 

o:

query.and().page(4).and().pageSize(5).and().fromDate(new java.util.Date) 

¿Es posible en Scala?

Respuesta

11

Se puede declarar los métodos como devolver this.type y luego regresar this de ellos:

trait PageParameter extends Parameterizable{ 
    def page(page: Int) : this.type = { put(("page" -> page.toString)); this } 
    def pageSize(pageSize: Int): this.type = { put(("pagesize" -> pageSize.toString)); this } 
} 

En el uso in situ, a continuación, se pueden encadenar las llamadas, ya que queríamos. Vea este ejemplo:

scala> trait Wibble { 
| def foo : this.type = { println("foo"); this } 
| } 
defined trait Wibble 

scala> trait Wobble extends Wibble { 
| def bar: this.type = { println("bar"); this } 
| } 
defined trait Wobble 

scala> trait Wubble extends Wibble { 
| def baz: this.type = { println("baz"); this } 
| } 
defined trait Wubble 

Ahora puedo probarlo

scala> new Wibble with Wobble with Wubble 
res0: java.lang.Object with Wibble with Wobble with Wubble = [email protected] 

scala> res0.bar.baz.foo 
bar 
baz 
foo 
res1: res0.type = [email protected] 
Cuestiones relacionadas