1

我遵循功能和反应域建模这本书的设计

对于某些服务方法,它仅将工作委托给存储库层。有没有办法减少这个样板:

trait FeedbackServiceImpl extends FeedbackService {
  override def saveTFE(feedback: TripFeedbackEvent) =
    Kleisli[Future, Context, Either[String, Id]] { ctx => ctx.feedbackRepo.save(feedback) }

  override def saveLFE(feedback: LibraryFeedbackEvent) =
    Kleisli[Future, Context, Either[String, Id]] { ctx => ctx.feedbackRepo.save(feedback) }

  override def findByUser(userId: Id) =
    Kleisli[Future, Context, Seq[FeedbackEvent]] { ctx => ctx.feedbackRepo.findByUser(userId) }

  override def all =
    Kleisli[Future, Context, Seq[FeedbackEvent]] { ctx => ctx.feedbackRepo.all }

  override def findByTip(tipId: Id) =
    Kleisli[Future, Context, Seq[FeedbackEvent]] { ctx => ctx.feedbackRepo.findByTip(tipId) }

}
4

2 回答 2

1

我们可以创建一个组合器:

private def kleisli[M[_], A](f: FeedbackRepository => M[A]) = Kleisli.kleisli(f).local[Context](_.feedbackRepo)

因此,我们获得了两件事:

  • 通过帮助类型推断机制避免声明类型
  • 避免ctx.feedbackRepo使用调用local

所以我们可以使用:

trait Feedbacks {
  def saveTFE(feedback: TripFeedbackEvent) = kleisli(_.save(feedback)) 
  def saveLFE(feedback: LibraryFeedbackEvent) = kleisli(_.save(feedback))
  def findByUser(userId: Id) = kleisli(_.findByUser(userId))
  ...
}
于 2016-06-01T19:09:05.657 回答
-1

你能定义一个完成所有样板的函数吗?就像是:

def repo2Kleisli[T](f: Repo => Future[T]): Kleisli[Future, Context, T]

您甚至可以使其隐含并将您的代码简化为:

 override def saveTFE(feedback: TripFeedbackEvent) = (repo: Repo) => repo.save(feedback)
于 2016-04-01T04:50:57.533 回答