2016-03-17 69 views
1

我按照書功能和無功領域建模如何減少樣板與Kleisli

而對於一些服務方式,它只是代表工作到存儲庫層的設計。有沒有辦法減少這個樣板:

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) } 

} 

回答

0

我們可以創建一個組合子我們獲得2件事:

  • 避免通過幫助類型推理機制聲明類型
  • 避免使用local

調用ctx.feedbackRepo所以我們可以使用:

trait Feedbacks { 
    def saveTFE(feedback: TripFeedbackEvent) = kleisli(_.save(feedback)) 
    def saveLFE(feedback: LibraryFeedbackEvent) = kleisli(_.save(feedback)) 
    def findByUser(userId: Id) = kleisli(_.findByUser(userId)) 
    ... 
} 
-1

你可以只定義一個函數,做所有的樣板?喜歡的東西:

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

你可以甚至可能使隱性和降低代碼的東西,如:因此

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

override def saveTFE(feedback: TripFeedbackEvent) = (repo: Repo) => repo.save(feedback)