开发者

Can Such An Object Be Considered Immutable?

I have designed a class containing some information about a given object which will be registered in an SQL Server database. I would like to make this object (deeply) immutable, but I also must assure that it gets registered only once. If this object implements the following pattern, can it still be considered immutable?

public class NewClass
{
    private bool registered;

    public string SomeProperty { get; private set; }

    public NewClass Register()
    {
        if (registered)
        {
            throw new NotImplementedException(/*arguments*/);
        }

        /* Register on DB here... */
        registered = true;
        return new NewClass(somePropertyFromDB);
    }

    public NewClass(string someProperty)
    {
        registered = false;
        SomePropery = someproperty;
    }
}

I would say that except for the boolean fi开发者_如何学Pythoneld registered the object is immutable, but this fields leaves me some doubts because it will actually change on the first time the Register method is executed... Can anyone please tell me how can I solve this problem and still make the object be immutable?


No, it's definitely not immutable. The registered value changes over the lifetime of the object.

To make it immutable, you mustn't allow the registered field to change over the lifetime of the object - instead, make Register return a new object which has a true value for registered

I'd also remove the private setter for SomeProperty, just having a getter and a readonly variable.

So something like this:

public class NewClass
{
    private readonly bool registered;
    private readonly string someProperty;

    public bool Registered { get { return registered; } }
    public string SomeProperty { get { return someProperty; } }

    public NewClass Register()
    {
        // Note the change of exception here
        if (registered)
        {
            throw new InvalidOperationException("Already registered");
        }

        return new NewClass(somePropertyFromDB, true);
    }

    // You may want to have a public constructor with just someProperty
    // which calls this one, which you could make private
    public NewClass(string someProperty, bool registered)
    {
        this.registered = registered.;
        this.someProperty = someproperty;
    }
}

Some notes:

  • Another option would be to have two separate classes, RegisteredFoo and UnregisteredFoo; that might make it easier to understand code using this class
  • There's nothing to stop someone calling Register twice, so making this immutable doesn't really help in terms of idempotency. As there's a natural side-effect (talking to the database) it's hard to make this truly functional.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜