gpt4 book ai didi

scala - Scala 中不可变的可组合构建器

转载 作者:行者123 更新时间:2023-12-04 07:25:41 25 4
gpt4 key购买 nike

我对如何改进下面的代码感兴趣。这个想法是构建一个不可变的可组合构建器。最后,构建器只是构建了一个 Map[String, Object]。我希望能够定义可重用的核心构建器组件,并让人们定义他们自己的附加构建器来扩展主构建器。我能够这样做,但不是没有丑陋的反射使用。代码如下所示:

object TestPizzaBuilder {
def main(args: Array[String]): Unit = {

val build = new PizzaBuilder()
.withCheese("blue")
.withSauce("tomato")
.build()

println(build)
}
}

object PizzaBuilder {
type BuilderParams = Map[String, Object]
}

class PizzaBuilder(params: BuilderParams = Map.empty) extends BaseBuilder[PizzaBuilder](params: BuilderParams)
with CheeseBuilder[PizzaBuilder]
with SauceBuilder[PizzaBuilder] {
}

abstract class BaseBuilder[A <: BaseBuilder[A]](params: BuilderParams)(implicit tag: ClassTag[A]) {

protected def _copy(tuples: (String, Object)*): A = {
val constr = tag.runtimeClass.getConstructors()(0)
constr.newInstance(params ++ tuples).asInstanceOf[A]
}

def build(): Map[String, Object] = {
params
}
}

trait CheeseBuilder[A <: BaseBuilder[A]] {
this: BaseBuilder[A] =>
def withCheese(cheese: String): A = _copy("cheese" -> cheese)
}

trait SauceBuilder[A <: BaseBuilder[A]] {
this: BaseBuilder[A] =>
def withSauce(sauce: String): A = _copy("sauce" -> sauce)
}

您是否有建议如何在这种情况下避免反射,同时保持构建器不可变,并允许将构建器组合成其他微小的构建器。

最佳答案

最小的变化是传递构造函数(作为函数)而不是 ClassTag:

abstract class BaseBuilder[A <: BaseBuilder[A]](params: BuilderParams)(constructor: BuilderParams => A) {

protected def _copy(tuples: (String, Object)*): A = constructor(params ++ tuples)

def build(): Map[String, Object] = {
params
}
}

// or class PizzaBuilder(params: BuilderParams = Map.empty) extends BaseBuilder[PizzaBuilder](params)(new PizzaBuilder(_))
case class PizzaBuilder(params: BuilderParams = Map.empty) extends BaseBuilder[PizzaBuilder](params)(PizzaBuilder)
with CheeseBuilder[PizzaBuilder]
with SauceBuilder[PizzaBuilder] {
}

关于scala - Scala 中不可变的可组合构建器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50417240/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com