我对产品有两种评论:
我希望将WorksFineRating实例存储在SQL中的WorksFine表中。我希望PriceOkayRating实例存储在SQL中的PriceOkay表中。
我正在寻找具有两种评级类型的以下模式:(问号有意识地表明这不是最终设计)
trait? ProductRating( rating: Int, productId: Int, userId: Int )
{
val sqlTable
def getRatings: ProductRating = doMagicSql( s"SELECT * FROM $sqlTable" )
}
case Class? WorksFineRating(rating, productId, userId) extends Rating( rating, productId, userId){ val sqlTable = "WorksFineRating" }
case Class? PriceOkayRating(rating, productId, userId) extends Rating( rating, productId, userId){ val sqlTable = "PriceOkayRating" }
以下是我在Scala中实际建模的方法:
trait ProductRating[ PR <: ProductRating[ PR ] ]{
val reviewId: Int
val userId: Int
val rating: Int
}
case class WorksFineRating(
reviewId: Int,
userId: Int,
rating: Int
) extends ProductRating[ WorksFineRating ]
case class PriceOkayRating(
reviewId: Int,
userId: Int,
rating: Int
) extends ProductRating[ PriceOkayRating ]
trait ProductRatingCompanion[ PR <: ProductRating[ PR ] ]
{
val sqlTable: String
def factory( reviewId: Int, userId:Int, rating:Int ): PR
def getAllFromSqlTable = {
Seq( factory( 1, 2, 3 ), factory( 4, 5, 6 ) )
}
}
object WorksFineRating
extends ProductRatingCompanion[ WorksFineRating ]
{
val sqlTable = "WorksFineRating"
def factory( reviewId: Int, userId:Int, rating:Int )
: WorksFineRating =
WorksFineRating( reviewId, userId, rating )
}
object PriceOkayRating
extends ProductRatingCompanion[ PriceOkayRating ]
{
val sqlTable = "PriceOkayRating"
def factory( reviewId: Int, userId:Int, rating:Int ): PriceOkayRating =
PriceOkayRating( reviewId, userId, rating )
}
object T extends App{
println( WorksFineRating.getAllFromSqlTable )
}
说明:
1)正如我在第一个代码大纲中所示,我不太习惯将sqlTable放入类中。我想并非所有实例都应该知道这一点。 (我觉得休息对我来说似乎很简单)。
问题:
1)我是否通过将FBounded多态性添加到ProductRating特性而过度复杂化?这不是必需的。它确实在ProductRatingCompanion对象中是必需的,因为已知工厂的返回类型是PR。不是吗?
2)我可以以某种方式摆脱'工厂'吗?代码几乎相同。我不太了解JVM,但是如果外部库使用这个类,它只会看到同伴的通用版本,这意味着在运行时,没有办法创建该类的实例。那是对的吗?我可以以某种方式将类型存储在对象中吗?喜欢类型T = RR.type? (它不起作用)
3)如何创建一个可以处理这两种类型的函数?就像一个函数,它接受一个参数“PriceOrFunctionality”并决定创建一个适当类的实例。如果你执行if-else,那么这个实例的类型实际上是两种类型的混合类型。因此,使用伴随对象的任何进一步操作都需要asInstanceOf调用。
任何建议都会很棒。我希望这个问题能够成为设计的一个很好的参考 - 所以我愿意进行很多修改并使其成为社区维基(我不想在这里获得积分),以便人们可以将其用作良好的OO设计的例子。如果你们能提供帮助,我会很感激。 (我将了解如何制作社区维基)
编辑:我不能将此问题作为社区维基。如果任何mod可以做到这一点,那将是伟大的。提前谢谢。