使用类型类和工厂方法时出现Scala类型不匹配错误

时间:2015-09-14 20:28:18

标签: scala

免责声明:我正在将现有的Java + spring webapp转换为scala + spring。所以我的设计仍然是javaish和面向对象。

我只能在这里简单解释几个关键组件。

应用程序在请求进入时实时计算一些数据指标。核心组件是DataContext [DBObject],它包含我们从数据库中提取的一些按摩数据,根据每个请求生成多个实例(avg,请求中包含的百分位数; DataContextBuilder [DBOject]具有填充(按摩)DataContext [DBObject]的业务逻辑,这些是单例对象(由spring注释定义;如果可以,我将更改为scala单例)。然后有ViewWorkers [DBObject,IsDimensionLike],它根据DataContext [DBObject]中保存的数据进行最终的单个度量计算。

以下是上述组件的定义。

trait DBObject
trait AggDBObject extends DBObject 
trait RawDBObject extends DBObject 
class Dimensions1Agg extends AggDBObject 
class Dimensions2Agg extends AggDBObject 
class Dimensions1Raw extends RawDBObject

trait IDataContext[A <: DBObject]  {
    var XsummaryData: A = _
    var XByDateData : Map[String, A] = _
}
class DataContext[A <: DBObject] extends IDataContext[A]{
    def restrictAccess = {.. some impl ..}
}

trait IDataContextBuilder[A <: DBObject] {
    def initDataPoints(dataContext: IDataContext[A]): Unit
}
class Dimension1AggContextBuilder extends IDataContextBuilder[Dimension1Agg] {
 .. override method impl..
}


trait IViewWorker[A <: DBObject] {
  def getData(
    DataContextMap: Map[Int, IDataContext[A]]
  ): Map[Int, Map[Int, List[DataView]]]  //DataView can be type parameter here!?
}

class AbstractViewWorker[A <: DBObject, C : IsDimensionLike] extends IViewWorker[A] {

    abstract def formula[A](dbObject: A): C

   def getData(DataContextMap: Map[Int, IDataContext[A]]) = {some common impl goes here. ..}

}
class Metrix1ViewWorker extends AbstractViewWorker[Dimension1Agg] 

对于以上所有DBObject,我可以创建一个代表每个的特定DataContext子类型,但我想使用DataContext本身键入不同的DBObject。 DataContext是在运行时根据某个请求参数创建的。

这是使用apply方法的伴随对象:

object DataContext {


  def apply(sId: Int, mId: Int): DataContext[_ <: DBObject]  = { 

    (sId, mId) match {

      case (1, 1) => {
        new DataContext[Dimension1Agg]()
      }
      case (1, 2)  => {
        new DataContext[Dimension1Raw]()
      }
    }
  }
}

我正在创建的对象是否有正确的返回类型的apply方法?如果我删除它然后我在调用站点获得一些复杂的返回类型&#34; val dataContext:DataContext [_&gt;:Dimension1Agg with Dimension1Raw&lt ;:DBObject] with Product with Serializable {..}&#34;

您是否看到上述工厂方法的一般问题?

无论如何,在将DataContext传递给DataContextBuilder

时出现以下错误
type mismatch; found : IDataContext[_$1] where type _$1 <: DBObject required: IDataContext[_$19] 

是_ $ 1和_ $ 19,因为scalac无法确定类型?

这是DataContextBuilderFactory对象

object IDataContextBuilder {

  def apply(sId: Int, daId: Int): IDataContextBuilder[_ <: DBObject]  = {

    (sId, daId) match {

      case (1, 1) => {
        new Dimension1AggContextBuilder

      }
      case (1, 2) => {
        new Dimension1RawContextBuilder
      }
    }
  }
}

将站点称为接收请求参数的DataService类,编排所有上述组件并撰写响应。我知道它不起作用,但我正在尝试进行渐进式重构。 DataService检查请求参数,将该信息传递给工厂方法以创建多个DataContext和DataContextBuilder以及DataWorker;调用所有DataContextBuilder的initDataPoints方法,等待它们完成;调用所有Dataworker的generateView方法,等待它们完成,最后组成响应。

编辑1:

以下两种定义类型或泛型的方法有何不同?

trait IDataContextBuilder[A <: DBObject] {

  def initMetrixDataPoints(dataContext: IDataContext[A]): Unit

}

trait IDataContextBuilder {

  def initMetrixDataPoints(dataContext: IDataContext[_ <: DBObject]): Unit
}

0 个答案:

没有答案