У меня есть черта
trait DataDef {
def getDataSource: java.sql.DataSource
}
А затем несколько других черт, которые наследуют эту черту, например
trait Postgres extends DataDef {
// Postgres implementation
}
и,
trait MySql extends DataDef {
// For My SQL
}
Идругой абстрактный класс (и я могу преобразовать его в черту, если требуется)
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
}
}
}
Проблема в том, что повторяется так много кода, и это не выглядит как элегантное решение.Я должен быть в состоянии вернуть Postgres
, MySql
только один раз, и мне не нужно повторять код снова и снова.
Я хочу что-то вроде:
def getStrategy(strategyType: String) {
// return Strategy here, like new StrategyA
}
def getDataDef(dataType: String) {
// return DataDef here
}
А потомЯ должен быть в состоянии смешать это, вот так:
getStrategy(strategyType) with getDataDef(dataType)
Я посмотрел на макросы, и они выглядят многообещающе, но очень сложно.Мне было интересно, есть ли другой, более простой способ достижения того, чего я хочу.