3

我正在为类似地图的容器实现一个非常简单的构建器模式:

trait KeyValueContainer[K,V] {
  private var props: Map[K, V] = new HashMap[K, V]
  private var built = false

  /**
   * Adds a key/value pair
   */
  def +=(key: K, value: V): KeyValueContainer[K,V] = {
    if (built)
      throw new BuilderException

    props = props + (key -> value)
    this
  }

  def build = {
    built = true
    this
  }
}

class MyContainer extends KeyValueContainer[String, Double]

在“new MyContainer()”上使用上述“+=”或“build”方法时,结果在两种情况下都是 KeyValueContainer[String,Double] 类型...

我很确定我在过去的某个地方读到过,这可能会以某种方式返回实际的 MyContainer 子类型。您会为此使用方法返回类型协方差(Java 风格),还是在您看来有更类型安全/更好的解决方案?

谢谢!

4

2 回答 2

1

这里是:

http://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html

该模式依赖于在编译时如何解析隐式。基本上,如果范围内有多个隐式,编译器会选择最具体的一个(在您的情况下,您需要的子类型构建器)。

通过这种方式,您可以在基类中进行泛型实现,并通过隐式参数获取子类构建器。

这是我为自己的一个项目所做的示例:

https://gist.github.com/hejfelix/8a0270855d498d7981f9

这种模式的另一个重要方面是显式自键入: http ://www.scala-lang.org/node/124

于 2013-04-14T14:17:52.007 回答
-1

我推荐这篇文章,它更简单,而且重点:

建造者模式

看看如何通过使用 this.type 来返回自己,并以此为基础。

trait PaginationParameters extends Parameters {
 var _pageSize: Option[Int] = None
 var _page: Option[Int] = None

 def pageSize(newPageSize: Int): this.type = {
  _pageSize = Some(newPageSize); this
 }

 def page(newPage: Int): this.type  = {
  _page = Some(newPage); this
 }

 override def parameters = super.parameters ++
        _pageSize.map("page-size" -> _) ++
        _page.map("page" -> _)
 }
}

干杯

于 2013-04-15T16:06:05.857 回答