这是 NOT 一个广泛的问题。
我使用Akka + Spray进行小型项目。但是,我注意到我一直在编写具有类似结构的代码,它们都有相似之处,例如,有些块看起来像这样:
val response = (secCompanyActor ? WebGetOneCompany)
.mapTo[TransOk]
.map(result => result.succeedOrNot match {
case true => (OK, result.company.get)
case false => (BadRequest, result.errorMessage)
})
complete(response)
另一个块看起来像这样:(唯一的区别是TransAllOk
而不是TransOK
)
val response = (secCompanyActor ? CasperGetAllCompanies)
.mapTo[TransAllOk].map(result => result.succeedOrNot match {
case true => (OK, result.companies.get)
case false => (BadRequest, result.errorMessage)
}).recover { case _ => (BadRequest, "An error has occurred! We will fix this")}
complete(response)
TransOK
和TransAllOK
的签名位于:
case class TransOk(company: Option[Company.Company], errorMessage: Option[String])
case class TransAllOk(companies: Option[List[Company.Company]], errorMessage: Option[String])
有时,我的程序中有一些简单的get->返回数据库查询看起来非常相似:
case Register =>
val result = DAL.db.withSession{ implicit session =>
MTurker.insert()
}
sender ! TransOk(result._1, result._2, result._3)
下一个在不同的对象上调用不同的方法,但结构是相同的:
case WebGetOneCompany =>
val result = DAL.db.withSession{ implicit session =>
Company.getOneCompany()
}
sender ! TransOk(result._1, result._2, result._3)
Company
和MTurker
都是对象。
什么类型的知识可以帮助我编写更简洁的代码来处理我当前的问题?泛型?
答案 0 :(得分:1)
如果您利用子类型多态性,您可以编写一个方法来处理此问题:
首先,让我们给所有响应消息一个共同的父节点,同样对于请求消息:
abstract class SecCompanyActorResponse
case class SecCompanyActorError(error: String) extends SecCompanyActorResponse
abstract class SecCompanyActorSuccess(result: Any) extends SecCompanyActorResponse
case class TransOk(company: Company.Company) extends SecCompanyActorResponse(company)
case class TransAllOk(companies: List[Company.Company]) extends SecCompanyActorResponse(companies)
abstract class SecCompanyActorRequest[T]
case object WebGetOneCompany extends SecCompanyActorRequest[Company.Company]
case object CasperGetAllCompanies extends SecCompanyActorRequest[List[Company.Company]]
然后我们可以写:
def querySecCompanyActor[T](message: SecCompanyActorRequest[T]): Either[String, T] = {
secCompanyActor ? message map {
case SecCompanyActorError(error) => Left(error)
case success: SecCompanyActorSuccess => Right(success.result.asInstanceOf[T])
}
}