免责声明:我正在将现有的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
}