4

使用我得到的案例类在 scala 中实现我的域模型

abstract class Entity {
    val _id: Option[BSONObjectID]
    val version: Option[BSONLong]
}

以及几个定义不同实体的案例类,例如

case class Person (
   _id: Option[BSONObjectID],
   name: String, 
   version: Option[BSONLong]
) extends Entity

我需要的是一种稍后从对实体进行操作的通用方法设置 _id 和版本的方法,因为我必须在所有实体上共享此行为并希望避免将其写下数百次 ;-)。我很想能够

def createID(entity: Entity): Entity = {
  entity.copy(_id = ..., version = ...)
}

...但是当然这不会编译,因为实体没有复制方法。它由编译器为每个单独的案例类生成......

在scala中实现这一目标的最佳方法是什么?

为了防止有人问:我必须使用案例类,因为这是第三方库从我收到的请求中为我提取的内容,而案例类实例是稍后序列化回 BSON / MongoDB 的内容......

4

2 回答 2

3

事实上,人们可以找到一种方法来实现这样的事情

为支持 copy(id=newId) 方法的所有案例类创建共同特征

但由于我的用例非常复杂,我宁愿只创建两个新类

class MongoId(var id : BSONObjectID = null) {
    def generate = {
        id = BSONObjectID.generate
    }
}

class MongoVersion(var version: Long = 0) {
    def update = {
        version = System.currentTimeMillis
    }
}

并在那里实现了关于这些字段的共享行为。当然,您必须相应地更改基类的定义:

abstract class Entity {
    def _id: MongoId
    def version: MongoVersion
}

说清楚:这仅在您希望在多个案例类中共享的行为仅影响(在我的案例中更改)一个属性时才有效...

于 2013-03-09T23:23:32.973 回答
0

实施一个特征会起作用吗?

trait MongoIdHandler {
  def createId(entity : Entity) : Option[BSONObjectID] = { ..}
  def setVersion(version :  String) : Unit = { ..}
}

case class Person (..) with MongoIdHandler ..

如果任何实例需要特殊版本的 id 生成器,它们可以覆盖 trait 提供的“默认”impl。

于 2013-03-09T18:12:15.843 回答