Reputation: 4385
I'm creating a new domain object mode. In this model, there are User
s and Post
s. In the future there will be more models (e.g. Comment
s). I'm trying to learn how to do this using scala to it's full extent. Here's a naive implementation:
class User(val id: String, val creationDate: DateTime, val name: String, val email: String)
class Post(val id: String, val creationDate: DateTime, val user: User, val title: String, val body: String)
And here's another approach attempting to get rid of the duplicate id
and creationDate
.
class Model(val id: String, val creationDate: DateTime)
class User(id: String, creationDate: DateTime, val name: String, val email: String) extends Model(id, creationDate)
class Post(id: String, creationDate: DateTime, val user: User, val title: String, val body: String) extends Model(id, creationDate)
I'd like to moderate some of my domain objects. To do this, I'd like to add an isApproved: Boolean
field.
class Model(val id: String, val creationDate: DateTime)
class User(id: String, creationDate: DateTime, val name: String, val email: String) extends Model(id, creationDate)
class Post(id: String, creationDate: DateTime, val user: User, val title: String, val body: String) extends Model(id, creationDate)
trait Moderated {
val isApproved: Boolean
}
class ModeratedPost(id: String, creationDate: DateTime, val user: User, val title: String, val body: String, val isApproved: Boolean) extends Post(id, creationDate, user, title, body) with Moderated
I'd also like to prevent bugs in my code by type aliasing user and post Ids.
type Id = String
type UserId = Id
type PostId = Id
class Model(val id: Id, val creationDate: DateTime)
class User(id: UserId, creationDate: DateTime, val name: String, val email: String) extends Model(id, creationDate)
class Post(id: PostId, creationDate: DateTime, val user: User, val title: String, val body: String) extends Model(id, creationDate)
trait Moderated {
val isApproved: Boolean
}
class ModeratedPost(id: String, creationDate: DateTime, val user: User, val title: String, val body: String, val isApproved: Boolean) extends Post(id, creationDate, user, title, body) with Moderated
At this point, I've got several questions.
Where should I define my type aliases? I think they have to be defined inside a class, trait, or object.
My goal in using type aliases for my Ids is to catch errors at compile time. I'd like UserId
and PostId
to be "subclasses" of Id. I.e. if a method took an Id
, I could pass in a PostId
. How should I do this?
My Moderated
trait does not feel very useful. I still have to declare the isApproved
on all classes that mix it in. Any tips here?
Upvotes: 1
Views: 1800
Reputation: 49705
Idiomatic scala would go something like:
sealed trait Id { def strVal: String }
case class UserId(strVal: String) extends Id
case class PostId(strVal: String) extends Id
trait Model { def id: Id, def creationDate: DateTime)
case class User(
id: UserId,
creationDate: DateTime,
name: String,
email: String
) extends Model
trait Post extends model {
def id: PostId
def user: User,
def title: String,
def body: String
)
trait Moderated { def isApproved: Boolean }
case class UnmoderatedPost(
id: PostId
creationDate: DateTime,
user: User,
title: String,
body: String,
) extends Post
case class ModeratedPost(
id: PostId,
creationDate: DateTime,
user: User,
title: String,
body: String,
isApproved: Boolean
) extends Post with Moderated
Upvotes: 1
Reputation: 1544
You can define your type aliases in package.scala which can be created for each package.
Lets say you have a simple package org.your.project. Create a file in directory org/your/project called: package.scala
package org.your.project
package object Types {
type Id = String
type UserId = Id
type PostId = Id
}
Then in the class you wish to use the type aliases add:
import org.your.project.Types._
I'd probably not use types for the reasons you are thinking of. A type of Id could also be an Int but you made it a String. Anyone reading the code would have to click around the code base to figure out what the Id really is.
Upvotes: 1