如何避免在我的情况下编写具有类似结构的代码?

时间:2014-07-09 01:23:57

标签: scala

这是 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)

TransOKTransAllOK的签名位于:

  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)

CompanyMTurker都是对象。

什么类型的知识可以帮助我编写更简洁的代码来处理我当前的问题?泛型?

1 个答案:

答案 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])
  }
}