When trying to turn a class with mutable state into an immutable one I am regularly having a hard time choosing between two alternatives: I can 1) either extract the state into another (immutable) state object and pass this state to the class with every method call (and return the new state) or 2) make the state part of the immutable class and return a new class instance with potentially modified state with every method call.
Here is an example in Scala:
This is where I'm coming from
class SomeApiWrapper(val credentials: ApiCredentials) {
var nonce = 1L // mutable field
def apiCall(someParam: String): Unit = {
// make api call
// increase nonce
}
}
Option 1 - Separate state
class SomeApiWrapper(val credentials: ApiCredentials) {
def apiCall(someParam: String, s: ApiWrapperState) = {
// get nonce from state
// api call
// return new state with increased nonce
}
}
Option 2 - New instance with every method call
class SomeApiWrapper(val credentials: ApiCredentials, val nonce: Long) {
def apiCall(someParam: String): SomeApiWrapper = {
// api call with nonce
SomeApiWrapper(credentials, nonce + 1)
}
}
I like the clear separation of configuration parameters (credentials) from the state in the constructor for option 1, however, it is a bit annoying that for every class I now have two (one extra for the state) and I have to pass around the state all the time.
Are there other good arguments for chosing the first or second option? Am I missing another option here? Should I do it in a completely different way? Is there some standard literature I shoudl read on this?
either extract the state into another (immutable) state object and pass this state to the class with every method call (and return the new state)
Really, how is this any different from having an object's members represent the state, as implicit inputs/returns to all instance methods? It just adds complexity.