scala 设计模式 面向切面编程 Aspect-Oriented Programming

abstract override

abstract override修饰符在这里的作用是通知编译器我们将进行可以叠加的修改。如果没有加入修饰符编译将会报错。

面向切面编程(Aspect-oriented programming)

users.json

[
  {
    "firstName":"lalalala",
    "lastName":"wang",
    "age": 26
  },
  {
    "firstName":"Ilvlv",
    "lastName":"li",
    "age": 26
  },
  {
    "firstName":"lala",
    "lastName":"zhao",
    "age": 26
  }
]

case class

package DesignPattern

case class Person(firstName:String,lastName:String,age:Int)

DataReader.scala

package DesignPattern

import org.json4s._
import org.json4s.jackson.JsonMethods._
trait DataReader {
  def readData():List[Person]
  def readDataInefficiently():List[Person]
}


class DataReaderImpl extends DataReader{
  implicit val formats = DefaultFormats
  private def readUntimed():List[Person] =
    parse(StreamInput(getClass.getResourceAsStream("file.json")))
      .extract[List[Person]]

  override def readData():List[Person] = readUntimed()


  override def readDataInefficiently(): List[Person] = {
    (1 to 10000).foreach{
      case num =>
        readUntimed()
    }
    readUntimed()
  }
}
object DataReaderExample {
  def main(args: Array[String]): Unit = {
    val dataReader = new DataReaderImpl
    println(s"I just read the following data efficiently ${dataReader.readData()}")
    println(s"I just read the following data unefficiently ${dataReader.readDataInefficiently()}")
  }
}

Timing our application without APO

通过传统的方式实现一个计时的操作,我们需要在整个项目种不断的出现 println 语句,或者是添加计时的方法在实现类中。通常添加一个方法是一个比较不错的选择,在一些情况下。但是在一些情况下,这些方法需要在不通的情况下调用,并且传入不同的参数。
按照我们的阐述,重构一下之前的代码

package DesignPattern

import org.json4s._
import org.json4s.jackson.JsonMethods._
trait DataReader {
  def readData():List[Person]
  def readDataInefficiently():List[Person]
}


class DataReaderImpl extends DataReader{
  implicit val formats = DefaultFormats
  private def readUntimed():List[Person] =
    parse(StreamInput(getClass.getResourceAsStream("file.json")))
      .extract[List[Person]]

  override def readData():List[Person] = {
    val startMillis = System.currentTimeMillis()
    val result = readUntimed()
    val time = System.currentTimeMillis() - startMillis
    println(s"readData took ${time} milisecoonds")
    result
  }


  override def readDataInefficiently(): List[Person] = {
    val startMillis = System.currentTimeMillis()
    (1 to 10000).foreach{
      case num =>
        readUntimed()
    }
    val result = readUntimed()
    val time = System.currentTimeMillis() - startMillis
    println(s"readData took ${time} milisecoonds")
    result
  }
}
object DataReaderExample {
  def main(args: Array[String]): Unit = {
    val dataReader = new DataReaderImpl
    println(s"I just read the following data efficiently ${dataReader.readData()}")
    println(s"I just read the following data unefficiently ${dataReader.readDataInefficiently()}")
  }
}

Timing our application with AOP

添加特质

package DesignPattern

trait LoggingDataReader extends DataReader {

  abstract override def readData(): List[Person] = {
    val startMillis = System.currentTimeMillis()
    val result = super.readData()
    val time = System.currentTimeMillis() - startMillis
    println(s"readDate took ${time} milliseconds.")
    result
  }
  abstract override def readDataInefficiently(): List[Person] = {
    val startMillis = System.currentTimeMillis()
    val result = super.readDataInefficiently()
    val time = System.currentTimeMillis() - startMillis
    println(s"readDate took ${time} milliseconds.")
    result
  }
}

修改对象

    val dataReader = new DataReaderImpl with LoggingDataReader

实现在scala 种使用aop

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章