Hen*_*wan 4 java oop setter scala builder
假设Product是在我无法调整的Java库中,所以通过调用setter实例化它:
val product = new Product
product.setName("Cute Umbrella")
product.setSku("SXO-2")
product.setQuantity(5)
Run Code Online (Sandbox Code Playgroud)
我更愿意做这样的事情:
val product = new Product {
_.setName("Cute Umbrella")
_.setSku("SXO-2")
_.setQuantity(5)
}
Run Code Online (Sandbox Code Playgroud)
或者更好的是:
val product =
new Product(name -> "Cute Umbrella", sku -> "SXO-2", quantity -> 5)
Run Code Online (Sandbox Code Playgroud)
Scala可以这样吗?
您可以导入setter,这样您就不需要限定调用:
val product = {
val p = new Product
import p._
setName("Cute Umbrella")
setSku("SXO-2")
setQuantity(5)
p
}
Run Code Online (Sandbox Code Playgroud)
如果Product不是最终的,您也可以匿名子类并在构造函数中调用setter:
val product = new Product {
setName("Cute Umbrella")
setSku("SXO-2")
setQuantity(5)
}
Run Code Online (Sandbox Code Playgroud)
一旦尝试使用属性名称和值的Map进行实例化,就会在求助于反射时丢失静态类型检查.像Apache Commons BeanUtils这样的库可以提供帮助,如果你还想走这条道路的话.
另一种方法是传递一系列匿名函数来调用每个setter,并编写一个实用程序方法将它们应用于对象
def initializing[A](a: A)(fs: (A => Unit)*) = { fs.foreach(_(a)); a }
initializing(new Product)(
_.setName("Cute Umbrella"),
_.setSku("SXO-2"),
_.setQuantity(5)
)
Run Code Online (Sandbox Code Playgroud)
您可以将Product对象创建为工厂,并在scala中调用它.像这样的东西:
object Product {
def apply(name: String, sku: String, quantity: Int) = {
val newProd = new Product()
import newProd._
setName(name)
setSku(sku)
setQuantity(quantity)
newProd
}
Run Code Online (Sandbox Code Playgroud)
然后你可以完全按照自己的意愿使用它(没有新的).
val product = Product(name = "Cute Umbrella", sku = "SXO-2", quantity = 5)
Run Code Online (Sandbox Code Playgroud)
(如果以上不编译,请道歉.在工作中无法访问Scala :(