In a partially mutable class, is it better to mix mutable fields with its immutable ones, or create a new class (or classes) that encapsulate them? Here's an example in C# of what I'm talking about:
interface IBedroom
{
int Volume { get; }
string Color { get; }
void Paint(string newColor);
}
Here's an implementation with mixed mutability in its fields:
class MixedMutabilityBedroom : IBedroom
{
readonly int volume;
string color;
public MixedMutabilityBedroom(int volume, string color = "")
{
this.volume = volume;
this.color = color;
}
public int Volume
{
get { return volume; }
}
public string Color
{
get { return color; }
}
public void Paint(string newColor)
{
color = newColor;
}
}
And one with separate mutability:
// first, a fully mutable helper class
class RoomColor
{
string value;
public RoomColor(string value)
{
this.value = value;
}
public string Value
{
get { return value; }
}
public void Change(string newValue)
{
value = newValue;
}
}
and the separated-mutability implementation:
class SeparatedMutabilityBedroom : IBedroom
{
readonly int volume;
readonly RoomColor color;
public SeparatedMutabilityBedroom(int volume, RoomColor color)
{
this.volume = volume;
this.color = color;
}
public int Volume
{
get { return volume; }
}
public string Color
{
get { return color.Value; }
}
public void Paint(string newColor)
{
color.Change(newColor);
}
}
I personally side with the latter style. In my experience, bugs that arise from state manipulation in concurrent scenarios are difficult to debug. As concurrency becomes the norm for programs, it seems that localizing mutability is a key factor to reducing debugging effort. In the second example we do not have to look over the entire class implementation to find out where state is manipulated. The entirety of SeparatedMutabilityBedroom
's mutability is localized to RoomColor
.
What do you think? Have I forgotten some points for consideration?