Scala面向对象的设计建议

时间:2014-11-21 10:34:55

标签: scala oop polymorphism

我对产品有两种评论:

  • 按建议工作(1至5)。
  • 价格没关系。 (1至5)。

我希望将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可以做到这一点,那将是伟大的。提前谢谢。

0 个答案:

没有答案