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) メソッドをサポートするすべてのケース クラスに共通のトレイトを作成する

しかし、私のユースケースでは非常に複雑なので、2 つの新しいクラスを作成することをお勧めします

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
}

明確にするために:これは、複数のケースクラスで共有したい動作が1つの属性にのみ影響する(私の場合は変更される)場合にのみ機能します...

于 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 ジェネレーターの特殊なバージョンを必要とする場合、それらは特性によって提供される「デフォルト」の impl をオーバーライドできます。

于 2013-03-09T18:12:15.843 に答える