mardi 7 avril 2015

Type safety when optional field is guaranteed to be present

Let's say I have a following case class:



case class Product(name: String, categoryId: Option[Long]/*, other fields....*/)


Here you can see that categoryId is optional.


Now let's say I have a following method in my DAO layer:



getCategoryProducts(): List[Product] = {
// query products that have categoryId defined
}


You see, that this method returns products, that are guaranteed to have categoryId defined with some value.


What I would like to do is something like this:



trait HasCategory {
def categoryId_!: Long
}
// and then specify in method signature
getCategoryProducts(): List[Product with HasCategory]


This will work, but then such a product will have two methods: categoryId_! and categoryId that smells bad.


Another way would be:



sealed trait Product {
def name: String
/*other fields*/
}
case class SimpleProduct(name: String, /*, other fields....*/) extends Product
case class ProductWithCategory(name: String, categoryId: Long/*, other fields....*/) extends Product
def getCategoryProducts: List[ProductWithCategory] = ...


This method helps to avoid duplicate methods categoryId and categoryId_!, but it requires you to create two case classes and a trait duplicating all the fields, which also smells.


My question: how can I use Scala type system to declare this specific case without these fields duplications ?


Aucun commentaire:

Enregistrer un commentaire