0

在部分可变的类中,将可变字段与其不可变字段混合,还是创建一个封装它们的新类(或多个类)更好?这是我正在谈论的 C# 中的一个示例:

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.

你怎么看?我是否忘记了一些需要考虑的要点?

4

1 回答 1

0

使用不可变数据结构进行编程是一种非常有用的技术,但很难根据一个简单的示例来评价整体最佳实践或建议。决定什么是最好的必须考虑其他因素,例如如何使用这个类并与之交互。

但是,假设您处于与该对象的多个写入者具有大量并发性的情况下,那么使对象部分不可变真的不会给您带来太多好处,因为您仍然会遇到问题。

在这种情况下,要么使用某种同步原语,要么使用完全不可变的对象。

这个答案谈到了一些使用完全不可变对象的技术。

于 2010-10-01T02:08:46.860 回答