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

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