如何以 Scala 方式处理横切关注点
How to handle cross cutting concerns the Scala way
我正在网上阅读有关横切关注点的内容,因为我刚刚在我的代码中实现了 Log4j。有些人说使用 AspectJ 没问题,而其他人则指出它破坏了函数式编程。 mixin 是 Scala 对横切关注点的解决方案。
但是,当我认为我会将特征扩展到一个本身不相关的对象/ class 时,我感到畏缩。
例如new Database with Logger
这里Logger
与Database
无关,只是如何混合提供日志记录。我更喜欢用 Scala 的方式来做,所以我想知道这就是人们所说的 mixins 的意思。
谁能告诉我如何在 Scala 中执行此操作的快速示例?
这是一个很大的话题,有很多潜在的 "correct" 答案。我个人最喜欢使用 "by name parameters" 或更高阶函数。
一个非常简单的例子:
object Logging {
def logCall[T](name: String)(block: => T): T = {
log.info(s"Invoking: $name")
block
}
}
这将允许您将它应用到一个对象中,该对象本身知道横切关注点(类似于用 java 中的内容注释包装方法调用):
class DB {
import Logging._
def insert(item: Something) = logCall("insert") {
???
}
}
或在调用站点:
import Logging._
def businessLogic() {
val user = ???
val result = logCall("insert user")(DB.insert(user))
println(result)
}
这样做的好处是它非常明确且不言自明(同样,您可能看重或不看重这些东西)。
我正在网上阅读有关横切关注点的内容,因为我刚刚在我的代码中实现了 Log4j。有些人说使用 AspectJ 没问题,而其他人则指出它破坏了函数式编程。 mixin 是 Scala 对横切关注点的解决方案。
但是,当我认为我会将特征扩展到一个本身不相关的对象/ class 时,我感到畏缩。
例如new Database with Logger
这里Logger
与Database
无关,只是如何混合提供日志记录。我更喜欢用 Scala 的方式来做,所以我想知道这就是人们所说的 mixins 的意思。
谁能告诉我如何在 Scala 中执行此操作的快速示例?
这是一个很大的话题,有很多潜在的 "correct" 答案。我个人最喜欢使用 "by name parameters" 或更高阶函数。
一个非常简单的例子:
object Logging {
def logCall[T](name: String)(block: => T): T = {
log.info(s"Invoking: $name")
block
}
}
这将允许您将它应用到一个对象中,该对象本身知道横切关注点(类似于用 java 中的内容注释包装方法调用):
class DB {
import Logging._
def insert(item: Something) = logCall("insert") {
???
}
}
或在调用站点:
import Logging._
def businessLogic() {
val user = ???
val result = logCall("insert user")(DB.insert(user))
println(result)
}
这样做的好处是它非常明确且不言自明(同样,您可能看重或不看重这些东西)。