如何处理横切关注Scala方式

7 aop scala cross-cutting-concerns scala-2.10

我正在网上阅读关于横切问题,因为我刚刚将Log4j实现到我的代码中.有些人说使用AspectJ是可以的,而其他人则指出它打破了函数式编程.这些混合物是Scala针对交叉问题的解决方案.

但是,当我想我将一个特征扩展到一个与自身无关的对象/类时,我感到畏缩.

例如 new Database with Logger

这里Logger没有任何关系Database,但它如何混合提供日志记录.我更喜欢Scala方式,所以我想知道这是mixins的意思.

有人可以告诉我一个如何在Scala中进行此操作的快速示例吗?

joh*_*ren 5

这是一个很大的主题,有很多潜在的"正确"答案.我个人最喜欢的是使用"按名称参数"或更高阶的功能.

一个非常简单的例子:

object Logging {
  def logCall[T](name: String)(block: => T): T = {
    log.info(s"Invoking: $name")
    block
  }
}
Run Code Online (Sandbox Code Playgroud)

这将允许您将它应用于一个本身知道交叉关注问题的对象(类似于在java中使用某些东西注释包装方法调用):

class DB {
  import Logging._
  def insert(item: Something) = logCall("insert") {
    ???
  }
}
Run Code Online (Sandbox Code Playgroud)

或者在通话现场:

import Logging._
def businessLogic() {
  val user = ???
  val result = logCall("insert user")(DB.insert(user))
  println(result)
}
Run Code Online (Sandbox Code Playgroud)

这样做的好处在于它非常明确且具有自我解释性(这也是你可能重视或不重要的事情).

  • 它肯定与在Java中使用全局变量不同,如果您希望在交叉关注问题中可用的依赖项,则可以将这些依赖项作为常规或隐式参数传递给交叉方法.没有什么要求Logging是一个单例,它只是通过这种方式使代码示例简短(因为你很少注入一个记录器). (2认同)