我有一些“遗留”的 Scala 代码(类似 Java),它进行一些数据访问。有一个装饰器可以跟踪 DAO 方法(收集指标)的使用情况,如下所示:
class TrackingDao(tracker: Tracker) extends Dao {
def fetchById(id: UUID, source: String): Option[String] = {
tracker.track("fetchById", source) {
actualFetchLogic(...)
}
}
...
}
我正在尝试将其建模为 Free monad。我为 DAO 操作定义了以下代数:
sealed trait DBOp[A]
case class FetchById(id: UUID) extends DBOp[Option[String]]
...
我看到两个选项:
a)我可以制作两个解释器DBOp
,一个执行实际的数据访问,另一个执行跟踪,并将它们组合在一起,或者
b)我使 Tracking 成为一个显式代数,并使用 Coproduct 在同一个for
组合中使用它们或者
c) 完全不同的东西!
第一个选项看起来更像是一种“装饰器”方法,它与 绑定DBOp
,第二个是更通用的解决方案,但需要显式调用“跟踪”代数。
另外,请注意source
原始fetchById
调用中的参数:它仅用于跟踪。我宁愿从 API 中删除它。
这是实际的问题:我如何为跟踪建模?