我正在研究将在数据库中持久保存的实体。以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"))
我想使用相同的用户代码(即最小化代码重复),同时拥有两种类型的用户:
我想在编译时尽可能严格地执行此操作。
我希望能够对所有用户进行相同的处理,除非我尝试从非持久用户获取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)
}
但是,我的未坚持用户的id
为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
对这些方法的想法?我从来没有这样做过,所以我不确定我是否理解所有后果。
答案 0 :(得分: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
可能有意义,因为您想在同一个类中表达某个字段可能具有值的。唯一的另一种方式似乎是拥有两个类(可能一个继承自另一个),只有一个具有id
字段。