码迷,mamicode.com
首页 > 其他好文 > 详细

Scala 堆叠Traits实现对方法的增强

时间:2015-08-12 19:58:16      阅读:238      评论:0      收藏:0      [点我收藏+]

标签:

Scala 堆叠Traits实现对方法或函数的增强

简单的来说,堆叠Trait类似于AOP,实现对方法功能的增强,而不去修改原有方法的逻辑。

比如我们实现一个队列,我们可以定义一个队列的抽象类,实现入队和出队操作,用scala这样写,和java差不多,


abstract class IntQueue {
  def get(): Int

  def put(x: Int)
}

我们去实现这个抽象类,

class BasicIntQueue extends IntQueue {
  private val buf = new ArrayBuffer[Int]

  override def get() = buf.remove(0)

  override def put(x: Int) {
    buf += x
  }
}

测试一下,

object Main87 {
  def main(args: Array[String]) {
    val queue = new BasicIntQueue
    queue.put(10)
    queue.put(20)
    println(queue.get())
    println(queue.get())
  }
}

这样是可以实现我们的功能的。但是我们想在put方法上实现更多的功能,比如说给入队的值加倍。

你可能会说直接去修改put方法的逻辑,这样也是可行的,但没有扩展性。比较好的方法还可以是继承父类在实现一个具体的类,put方法的逻辑是加倍。

class BasicIntQueue2 extends IntQueue {
  private val buf = new ArrayBuffer[Int]

  override def get() = buf.remove(0)

  override def put(x: Int) {
    buf += 2 * x
  }
}

如果现在逻辑又改了,我们要过滤入队的值,比如说值小于等于0 ,那么丢弃,不入队,然后把过滤后的值加倍。这样的话是不是还要实现一个具体的类,实现这样的逻辑?当然可以这么做。然而在java中,运用AOP的思想可以给put方法写一个切面,作用于加倍的put方法。加逻辑,就要写切面,这样也不是很好。在scala中实现这样的功能就是堆叠trait。

我们定义加倍的Trait,

trait Doubling extends IntQueue {
  abstract override def put(x: Int) {
    println("doubling")
    super.put(2 * x)
  }
}

定义过滤的Trait,

trait Filtering extends IntQueue {
  abstract override def put(x: Int) {
    println("filtering")
    if (x >= 0) super.put(x)
  }
}

这两个trait相当于一个一个的切面,如何把这些逻辑加到基础的put方法上呢?我们可以这样来做

class MyQueue00 extends BasicIntQueue with Doubling with Filtering

object Main87 {
  def main(args: Array[String]) {
    val q = new MyQueue00
    q.put(-1)
    q.put(0)
    q.put(1)
    println(q.get())
    println(q.get())
  }
}

运行结果,

filtering

filtering

doubling

filtering

doubling

0

2

这个问题就这么优雅的解决了,这样做的好处就是可以很好的复用代码。

一个完成的demo

package com.usoft4

import scala.collection.mutable.ArrayBuffer

abstract class IntQueue {
  def get(): Int

  def put(x: Int)
}

class BasicIntQueue extends IntQueue {
  private val buf = new ArrayBuffer[Int]

  override def get() = buf.remove(0)

  override def put(x: Int) {
    buf += x
  }
}

class BasicIntQueue2 extends IntQueue {
  private val buf = new ArrayBuffer[Int]

  override def get() = buf.remove(0)

  override def put(x: Int) {
    buf += 2 * x
  }
}

trait Doubling extends IntQueue {
  abstract override def put(x: Int) {
    println("doubling")
    super.put(2 * x)
  }
}


trait Incrementing extends IntQueue {
  abstract override def put(x: Int) {
    println("incrementing")
    super.put(x + 1)
  }
}

trait Filtering extends IntQueue {
  abstract override def put(x: Int) {
    println("filtering")
    if (x >= 0) super.put(x)
  }
}

class MyQueue0 extends BasicIntQueue with Doubling

class MyQueue00 extends BasicIntQueue with Doubling with Filtering

object Main87 {
  def main(args: Array[String]) {
    val queue = new BasicIntQueue
    queue.put(10)
    queue.put(20)
    println(queue.get())
    println(queue.get())

    val q = new MyQueue00
    q.put(-1)
    q.put(0)
    q.put(1)
    println(q.get())
    println(q.get())

    val myQueue = new MyQueue0
    myQueue.put(10)
    println(myQueue.get())

    val myQueue2 = (new BasicIntQueue with Filtering with Incrementing)
    myQueue2.put(-1)
    println("put end")
    myQueue2.put(0)
    println("put end")
    myQueue2.put(1)
    println("put end")
    println(myQueue2.get())
  }
}

=====================END=====================

Scala 堆叠Traits实现对方法的增强

标签:

原文地址:http://my.oschina.net/xinxingegeya/blog/491539

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!