【问题标题】:Convert types from A to B and vice versa Scala将类型从 A 转换为 B,反之亦然 Scala
【发布时间】:2013-08-10 14:22:49
【问题描述】:

在我们的网络服务接口的一部分,我们创建了不依赖于任何特定平台/供应商 API 的更轻量级的面向客户端的 API。

现在,这些服务特征的 impl 必须将这些携带传入数据的平台无关类型转换为供应商特定类型,以便 impl 方法继续按原样工作。请注意,我们无法更改供应商 API 上的任何代码。我想我们必须创建某种适配器/翻译 API,可以双向进行这种类型转换。一些供应商类型非常神秘。例如更轻量级的服务接口可能有一个扁平类型来承载所有数据,而供应商 API 有层次类型,可以接受输入数据等。返回类型也是如此。在 Scala 中实现这一目标的最佳方法是什么?

编辑:示例

case class A(var1,var2,var3,var4,var5,var6)

public Class B{

  private C c;
  private D d;

}

case 类是一个扁平结构,包含所有需要的数据,而另一方面,来自类 A 的数据将填充到 B (var2,var3)、C(var4,var5)、D(var6) 等。还有我忘了提到供应商 API 都是基于 Java 的。

谢谢,

【问题讨论】:

  • 太宽泛了。对涉及的问题进行适当分析以解决您的具体情况远远超出了 SO 的范围。
  • Function1[A,B] 从 A 转换为 B。除此之外,如果没有更具体地描述您要实现的计算,我不知道任何人如何回答这个问题。
  • 很公平。用示例编辑过的帖子。如果需要进一步澄清,请告诉我。

标签: scala functional-programming scalaz


【解决方案1】:

我想说,您可能可以利用“拉皮条”模式在两者之间来回切换。这是我在应用程序中使用的一大块东西。我只转换一种方式,但您可以看到如何使用另一种隐式方式,您可以实现返回原始/您的格式的逻辑。

// implicits for pimping 
implicit def pimpUser(user: User) = PimpedUser(user)
implicit def pimpLimitedViewUser(user: LimitedViewUser) = PimpedLimitedViewUser(user)

@entity
case class User(@serializer(classOf[UUIDOptionSerializer]) @id @column(name = "id") override val id: Option[UUID] = None,
                @serializer(classOf[DateOptionSerializer]) @column(name = "created_on") override val createdOn: Option[Date] = None,
                @serializer(classOf[DateOptionSerializer]) @column(name = "modified_on") override val modifiedOn: Option[Date] = None,
                @serializer(classOf[StringOptionSerializer]) @column(name = "first_name") firstName: Option[String] = None,
                @serializer(classOf[StringOptionSerializer]) @column(name = "last_name") lastName: Option[String] = None,
                @serializer(classOf[StringOptionSerializer]) @column(name = "email_address") emailAddress: Option[String] = None,
                @serializer(classOf[StringOptionSerializer]) @column(name = "password_salt") passwordSalt: Option[String] = None,
                @serializer(classOf[StringOptionSerializer]) @column(name = "password_hash") passwordHash: Option[String] = None,
                @serializer(classOf[IntOptionSerializer]) @column(name = "extension") extension: Option[Int] = None,
                devices: Set[Device] = Set.empty,
                @serializer(classOf[RingModeSerializer]) @column(name = "ring_mode") ringMode: RingMode = Waterfall) extends IdBaseEntity[UUID] {
  def this() = this(None, None, None, None, None, None, None, None, None, Set.empty[Device], Waterfall)

  override def equals(other: Any): Boolean =
    other match {
      case that: User => (that canEqual this) && (this.id match {
        case Some(uuid) => that.id match {
          case Some(thatUuid) => uuid == thatUuid
          case None => false
        }
        case None => false
      })
      case _ => false
    }

  override def hashCode: Int = this.id match {
    case Some(uuid) => 41 * (41 + uuid.hashCode())
    case None => super.hashCode
  }

  override def canEqual(other: Any): Boolean = other.isInstanceOf[User]

  def asAvailable: User = {
    User.devices.set(this)(devices.map(_.asAvailable))
  }

  def asUnavailable: User = {
    User.devices.set(this)(devices.map(_.asUnavailable))
  }
}

object User {
  implicit val userIso = Iso.hlist(User.apply _, User.unapply _)

  val id = Lens[User] >> _0
  val createdOn = Lens[User] >> _1
  val modifiedOn = Lens[User] >> _2
  val firstName = Lens[User] >> _3
  val lastName = Lens[User] >> _4
  val emailAddress = Lens[User] >> _5
  val passwordSalt = Lens[User] >> _6
  val passwordHash = Lens[User] >> _7
  val extension = Lens[User] >> _8
  val devices = Lens[User] >> _9
  val ringMode = Lens[User] >> _10
}

case class LimitedViewUser(id: Option[UUID], createdOn: Option[Date], modifiedOn: Option[Date], firstName: Option[String], lastName: Option[String]) {
  def this(user: User) = this(user.id, user.createdOn, user.modifiedOn, user.firstName, user.lastName)
}

case class PimpedUser(underlying: User) {
  def limited = LimitedViewUser(underlying)
}

case class PimpedLimitedViewUser(underlying: LimitedViewUser) {
  def normal = /* do something here to transform back to yours/the normal one */
}

// As long as those implicits are brought into scope, you will be able to do this:

val user: User = /* ... */
val limitedViewUser: LimitedViewUser = user.limited
val normalUser: User = limitedViewUser.normal

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 1970-01-01
    • 2020-10-24
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多