2011-08-05 18 views
6

Mam następujący kod:Czy można łączyć metody z różnych cech?

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 

chciałbym zrobić coś takiego:

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

lub:

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

Czy jest możliwe w Scala?

Odpowiedz

11

Można zadeklarować metody jak powrocie this.type a następnie powrócić this z nich:

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 } 
} 

Na miejscu użytkowania, można wtedy łańcuch połączeń jak chciałeś. Zobacz poniższy przykład:

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 

Teraz mogę go przetestować

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] 
Powiązane problemy