Scala return "partial" class 稍后必须与特征混合
Scala return "partial" class which must be mixed-in with trait later
我有一个特点
trait DataDef {
def getDataSource: java.sql.DataSource
}
然后是继承了这个trait的其他几个trait,比如
trait Postgres extends DataDef {
// Postgres implementation
}
并且,
trait MySql extends DataDef {
// For My SQL
}
还有另一个抽象class(如果需要,我可以将其转换为特征)
abstract class Strategy[T](strategyType: String) {
self: DataDef =>
def lookup(): Stream[T] = {
// use self.getDataSource and strategyType here
}
}
这样我就可以将策略和数据的代码分开。例如,
class StrategyA extends Strategy[Int]("typeA") {
self: DataDef =>
// implementation of this strategy
}
现在,我要做的是将这两者连接在一起,以便当用户传递特定的 strategyType 和 DataDef 类型时,我可以传递相关的对象。到目前为止我所拥有的是:
class getStrategy(strategyType: String, dataType: String) {
strategyType match {
case "typeA" =>
dataType match {
case "postgres" => return StrategyA with Postgres
case "mysql" => return StrategyA with MySql
}
case "typeB" =>
dataType match {
case "postgres" => return StrategyB with Postgres
case "mysql" => return StrategyB with MySql
}
}
}
问题是重复的代码太多,看起来不像是优雅的解决方案。我应该能够 return Postgres
, MySql
一次,而不需要一遍又一遍地重复代码。
我想要这样的东西:
def getStrategy(strategyType: String) {
// return Strategy here, like new StrategyA
}
def getDataDef(dataType: String) {
// return DataDef here
}
然后我应该可以混合它,像这样:
getStrategy(strategyType) with getDataDef(dataType)
我研究了宏,它们看起来很有前途,但非常复杂。我想知道是否有任何其他更简单的方法来实现我想要的。
不是您真正想要的:with
生活在类型世界中,而不是在值世界中,并且不能从方法返回类型。
但是如果你使用组合而不是继承,你可以这样做,例如
abstract class Strategy[T](strategyType: String, self: DataDef) {
// optional
// import self._
def lookup(): Stream[T] = {
// use self.getDataSource and strategyType here
}
}
class StrategyA(self: DataDef) extends Strategy[Int]("typeA", self) {
// implementation of this strategy
}
def getStrategy(strategyType: String): DataDef => Strategy {
// return e.g. new StrategyA(_)
}
def getDataDef(dataType: String) {
// return DataDef here
}
然后
getStrategy(strategyType)(getDataDef(dataType))
我有一个特点
trait DataDef {
def getDataSource: java.sql.DataSource
}
然后是继承了这个trait的其他几个trait,比如
trait Postgres extends DataDef {
// Postgres implementation
}
并且,
trait MySql extends DataDef {
// For My SQL
}
还有另一个抽象class(如果需要,我可以将其转换为特征)
abstract class Strategy[T](strategyType: String) {
self: DataDef =>
def lookup(): Stream[T] = {
// use self.getDataSource and strategyType here
}
}
这样我就可以将策略和数据的代码分开。例如,
class StrategyA extends Strategy[Int]("typeA") {
self: DataDef =>
// implementation of this strategy
}
现在,我要做的是将这两者连接在一起,以便当用户传递特定的 strategyType 和 DataDef 类型时,我可以传递相关的对象。到目前为止我所拥有的是:
class getStrategy(strategyType: String, dataType: String) {
strategyType match {
case "typeA" =>
dataType match {
case "postgres" => return StrategyA with Postgres
case "mysql" => return StrategyA with MySql
}
case "typeB" =>
dataType match {
case "postgres" => return StrategyB with Postgres
case "mysql" => return StrategyB with MySql
}
}
}
问题是重复的代码太多,看起来不像是优雅的解决方案。我应该能够 return Postgres
, MySql
一次,而不需要一遍又一遍地重复代码。
我想要这样的东西:
def getStrategy(strategyType: String) {
// return Strategy here, like new StrategyA
}
def getDataDef(dataType: String) {
// return DataDef here
}
然后我应该可以混合它,像这样:
getStrategy(strategyType) with getDataDef(dataType)
我研究了宏,它们看起来很有前途,但非常复杂。我想知道是否有任何其他更简单的方法来实现我想要的。
不是您真正想要的:with
生活在类型世界中,而不是在值世界中,并且不能从方法返回类型。
但是如果你使用组合而不是继承,你可以这样做,例如
abstract class Strategy[T](strategyType: String, self: DataDef) {
// optional
// import self._
def lookup(): Stream[T] = {
// use self.getDataSource and strategyType here
}
}
class StrategyA(self: DataDef) extends Strategy[Int]("typeA", self) {
// implementation of this strategy
}
def getStrategy(strategyType: String): DataDef => Strategy {
// return e.g. new StrategyA(_)
}
def getDataDef(dataType: String) {
// return DataDef here
}
然后
getStrategy(strategyType)(getDataDef(dataType))