1

我正在构建一个应用程序,它应该采用一个参数来指定要使用的给定数据结构的实现。比如说,参数的超类型是Super,我提供了很多SubX的实现。我的应用程序的用户可能还提供了在编译时未知的 SubY。

在应用程序中,参数将被传递,并将用于创建 Sub_ 的实例,调用 Super 中定义的方法,并用作参数化类型中的参数。

如果它只是用于参数化类型,我也可以让我的类参数化,这样就可以了。但是,我需要创建此类对象的实例,所以我想知道配置我的应用程序的最佳方式是什么。

我应该将类型和工厂作为参数传递吗?我发现工厂模式很难看,并想避免这种方法。此外,传递的参数太多(我的应用程序实际上需要几个这样的参数)。

我应该创建一个对象并将此配置粘贴在那里吗?是否可以在运行时解析对象对象,从而在编译时不知道配置?

编辑:理想情况下,我想要类似下面的代码。您能否提供一个基于此的最小工作示例?

class Test[Type <: Super] { 
   def main {
       val testVal: Type = new Type()
       testVal.methodDefinedInSuper()
    }
 }
4

2 回答 2

2

使用工厂。如果它们太多并且您不想创建工厂工厂来统一它们,那么使用依赖注入框架来做到这一点。依赖注入框架甚至支持 XML 配置,这似乎符合你想要做的。

如果您不知道任何依赖注入框架,请首先检查您正在使用的任何框架是否尚未提供它,如果没有,请查看Google Guice

以工厂为例:

trait Factory[T] {
  def newInstance(): T
}

class Test[Type <: Super](typeFactory: Factory[Type]) { 
  def main {
     val testVal: Type = typeFactory.newInstance()
     testVal.methodDefinedInSuper()
  }
}

谷歌 GUICE 示例:

class Test[Type <: Super] { 
  @Inject val testVal: Type = _
  def main {
     testVal.methodDefinedInSuper()
  }
}

请注意,Google Guice 上的这种注入方式是最不推荐的。我使用它是因为它也是最简洁的,可以提供一个总体视图。

但是请注意,Type <: Super在这两种情况下都没有理由使用。该界限并没有为您带来任何好处,因此您可以像这样重写它们:

class Test(typeFactory: Factory[Super]) { 
  def main {
     val testVal: Super = typeFactory.newInstance()
     testVal.methodDefinedInSuper()
  }
}

class Test { 
  @Inject val testVal: Super = _
  def main {
     testVal.methodDefinedInSuper()
  }
}

无论如何,在第一种情况下,您将工厂作为构造函数参数传递,而在第二种情况下,您使用一个 Guice 绑定来告诉 Guice 它应该使用什么来初始化testVal

于 2012-07-03T16:00:52.633 回答
1

传递带有类型参数的对象并期望基于类型参数以不同方式工作的对象是行不通的,因为由于类型擦除,这些参数仅在编译时存在。

(好的,好的,你可以使用即将被弃用的清单,或者可能是 2.10 中的新类型标签,但是对于日常应用程序代码应该避免这种巫术。)

于 2012-07-03T15:35:49.323 回答