Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the most concise way to construct/build JavaBean objects in Scala?

Let's say Product is in a Java library that I can't tweak, so to instantiate it by calling setters:

val product = new Product
product.setName("Cute Umbrella")
product.setSku("SXO-2")
product.setQuantity(5)

I'd prefer to be able to do something like this:

val product = new Product {
  _.setName("Cute Umbrella")
  _.setSku("SXO-2")
  _.setQuantity(5)
}

or better yet:

val product =
  new Product(name -> "Cute Umbrella", sku -> "SXO-2", quantity -> 5)

Is something like this possible with Scala ?

like image 802
Hendy Irawan Avatar asked Dec 10 '22 05:12

Hendy Irawan


1 Answers

You can import the setters so you don't need to qualify the calls:

val product = {
  val p = new Product
  import p._

  setName("Cute Umbrella")
  setSku("SXO-2")
  setQuantity(5)

  p
}

If Product isn't final, you could also anonymously subclass it and call the setters in the constructor:

val product = new Product {
  setName("Cute Umbrella")
  setSku("SXO-2")
  setQuantity(5)
}

As soon as you try to instantiate with a Map of property names and values, you lose static type checking, as you resort to reflection. Libraries like Apache Commons BeanUtils can help out, if you still want to go down that path.

Yet another approach is to pass a sequence of anonymous functions to call each setter, and write a utility method to apply them to the object

def initializing[A](a: A)(fs: (A => Unit)*) = { fs.foreach(_(a)); a }

initializing(new Product)(
  _.setName("Cute Umbrella"),
  _.setSku("SXO-2"),
  _.setQuantity(5)
)
like image 104
retronym Avatar answered Dec 28 '22 07:12

retronym