В частично изменяемом классе лучше ли смешивать изменяемые поля с его неизменяемыми или создавать новый класс (или классы), которые их инкапсулируют? Вот пример на С# того, о чем я говорю:
interface IBedroom
{
int Volume { get; }
string Color { get; }
void Paint(string newColor);
}
Вот реализация со смешанной изменчивостью в полях:
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;
}
}
И один с отдельной изменчивостью:
// 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;
}
}
и реализация разделенной изменчивости:
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);
}
}
Я лично сторонник последнего стиля. По моему опыту, ошибки, возникающие при манипулировании состоянием в параллельных сценариях, трудно отлаживать. По мере того, как параллелизм становится нормой для программ, кажется, что локализация изменчивости является ключевым фактором сокращения усилий по отладке. Во втором примере нам не нужно просматривать всю реализацию класса, чтобы выяснить, где происходит манипулирование состоянием. Вся изменчивость SeparatedMutabilityBedroom
локализована в RoomColor
.
Что вы думаете? Я забыл некоторые моменты для рассмотрения?