Using Java beans will destroy your functional code. I keep coming across code that implements setters and getters in Scala code. There are multiple problems with this when it comes to functional programming.
Scala code should use case classes, not mutable java beans. This will create code which is automatically thread safe without any mutex locking synchronization and which is easier to maintain and reason about, as it is immediately created with the correct state and its state remains the same for the application’s life time.
An example of what not to do, using Scala’s setters:
ode. There are multiple problems with this when it comes to functional programming.
Scala code should use case classes, not mutable java beans. This will create code which is automatically thread safe without any mutex locking synchronization and which is easier to maintain and reason about, as it is immediately created with the correct state and its state remains the same for the application’s life time.
An example of what not to do, using Scala’s setters:
class Name{
//Bad: look at all the boilerplate!
var _first: String = ""
var _last: String = ""
def first_= (f: String): Unit = _first = f
def first = _first
def last_= (l: String): Unit = _last = l
def last = _last
override def toString(): String = s"${_first} ${_last}"
}
val n = new Name()
n.first = "joe"
n.last = "smith"
def doSomethingWithName(name: Name): Unit = {
//Bad: now we have to synchronize if there are multiple threads at work
name.synchronized{
println(n)
}
}
doSomethingWithName(n)
First, while Java beans are always initialized to an incorrect state by design and then, as the setters are called, they gradually move towards correctness. This means that their state cannot be trusted because it can all change at any time. How does doSomething(name) know when it can start working on the name object, when its state can be still incomplete. The other issue is that functional code will expect not to have to lock objects. When using Java-bean style objects we will constantly have to go against the conventions of functional apps by worrying about the thread safety of these mutable objects. Then there’s also the fact that this code is very verbose.
Functional code expects immutable objects, uses some function to transform them, then creates new copies. But it typically doesn’t mutate objects. Immutable objects make it both easier to reason about the code and also make it run faster since we save cycles by not having to lock objects. A nice side effect is that we avoid deadlocks altogether. Because Java beans break this contract we can no longer rely on functional style locking free code, when using them.
Use case classes like this instead:
case class NameCC(first: String, last: String)
val n2 = NameCC("joe", "smith")
def doSomethingWithName2(name: NameCC) = {
println(name)
}
doSomethingWithName2(n2)
Get the sample code from ScalaGettersSetterAntiPattern