1

DBに永続化されるエンティティのモデリングに取り組んでいます。例として User エンティティを使用すると、次のように操作したいと思います。

val userBeforePersisting = new User("Joe", "joe@gmail.com")

// DB access code (where rs is a ResultSet)
val foundUser = new User(rs.getLong("id"), rs.getString("name"), rs.getString("email"))

2 種類のユーザーを持ちながら、同じユーザー コードを使用したい (つまり、コードの重複を最小限に抑えたい)。

  1. 事前永続化されたユーザーには ID がありません
  2. DB から取得した永続ユーザーには ID があります

コンパイル時にこれをできるだけ厳密に実施したいと思います。

永続化されていないユーザーから ID を取得しようとすると、エラーが発生するか、コンパイルされない場合を除いて、すべてのユーザーを同じように処理できるようにしたいと考えています。

このような個別のクラスを作成する必要は避けたい

class NewUser(val name: String, val email: String)
class PersistedUser(val id: Long, val name: String, val email: String)

コードの重複 (名前と電子メール フィールド) のため、このソリューションは好きではありません。

これが私が考えていることのようなものです:

class User(val id: Long, val name: String, val email: String) {
  this(name: String, email: String) = this(0l, name, email)
  this(id: Long, name: String, email: String) = this(id, name, email)
}

しかし、永続化されていないユーザーにはidof があり0lます。

別のアプローチを次に示します。

trait User {
  val name: String
  val email: String
}

class NewUser(val name: String, val email: String) extends User

class PersistedUser(val id: Long, val name: String, val email: String) extends User

これにより、必要なコンパイル時のチェックが得られます。これに欠点があるかどうかはわかりません。

多分私はこのようなことを試すことができます:

class User(val name: String, val email: String)
trait Persisted { val id: Long }
class PersistedUser(val id: Long, val name: String, val email: String)
  extends User(name, email)
  with Persisted

これらのアプローチについて何か考えはありますか?私はこのようにしたことがないので、すべての結果を理解しているかどうかはわかりません.

4

1 に答える 1

3

の使用が考えられますOption

class User(val id: Option[Long], val name: String, val email: String)

したがって、永続化されたユーザーには があり、永続id化されてSome(id)いないユーザーには がありNoneます。

id便宜上、次のデフォルト値を付与できNoneます。

class User(val id: Option[Long] = None, val name: String, val email: String)

// When you have an id...
val foundUser = new User(Some(rs.getLong("id")), 
    name = rs.getString("name"), email = rs.getString("email"))

// When you don't
val userBeforePersisting = new User(name = "Joe", email = "joe@gmail.com")

// However this will throw a runtime error:
val idThatDoesntExist: Long = userBeforePersisting.id.get

これは、マルチコンストラクターの例でも機能するはずです。

class User(val id: Option[Long], val name: String, val email: String) {
  def this(name: String, email: String) = this(None, name, email)
  def this(id: Long, name: String, email: String) = this(Some(id), name, email)
}

特定のフィールドが値を持つかどうかを同じクラスOptionで表現したいので、理にかなっていると思いました。他の唯一の方法は、2 つのクラス (おそらく一方は他方から継承) を持ち、1 つだけがフィールドを持っているようです。id

于 2012-12-12T05:45:03.760 に答える