Code Contracts #6: Modelling constraints and state

(Note: this article has been updated on 2009/05/16 by replacing the example and adding some more information)

Modelling constraints on class properties and valid state of classes explicitly is an interesting topic and sometimes I catch myself being frustrated by the lack of handling these aspects through current programming languages. With „constraint“ I mean a condition on one class property or on a set, which equals a subset of the properties for the class. The same is true for the „state of a class“. Periodically I run into situations, where I have for example two properties, whose values depend on each other. And what I want is to express explicitly, that when property 1 is in state X, then property 2 must be in state Y and vice versa and that this constraint on those properties (their depending state) mustn’t be broken!

Let’s consider a (very) little example in form of the following class MinMax:

public class MinMax
{
    public int MinValue { get; set; }
    public int MaxValue { get; set; }
}

Not too impressive, isn’t it? 😉 But as you can imagine, there is one obvious constraint: MinValue <= MaxValue. Two other constraints are related to each property for itself – they mustn’t be less than 0: MinValue >= 0 and MaxValue >= 0 must be true. If those 3 conditions are true, then the class can be seen to be in a valid state. And in this case, we want to ensure this valid state all the time. The question follows quickly: How to model these constraints? Normally, you as programmer wouldn’t be very concerned about that. For example, in the setters of MinValue and MaxValue, you would check the constraints and throw an exception, if they don’t hold:

public class MinMax
{
    private int _MinValue;
    public int MinValue {
        get { return _MinValue; }
        set
        {
            if (value %gt; MaxValue)
                throw new ArgumentException("value can't be greater than MaxValue");
            if (value < 0)
                throw new ArgumentException("value can't be less than 0");

            _MinValue = value;
        }
    }

    private int _MaxValue;
    public int MaxValue
    {
        get { return _MaxValue; }
        set
        {
            if (value < MinValue)
                throw new ArgumentException("value can't be less than MaxValue");
            if (value < 0)
                throw new ArgumentException("value can't be less than 0");

            _MaxValue = value;
        }
    }
}

There’s an even better way, when you use a Guard class for that. Better, because you’ve outsourced the exception throw into the guard and you can do additional things there like logging something:

public class MinMax
{
    private int _MinValue;
    public int MinValue
    {
        get { return _MinValue; }
        set
        {
            Guard.Against<ArgumentException>(
                value > MaxValue, "value can't be greater than MaxValue");
            Guard.Against<ArgumentException>(
                value < 0, "value can't be less than 0");

            _MinValue = value;
        }
    }

    private int _MaxValue;
    public int MaxValue
    {
        get { return _MaxValue; }
        set
        {
            Guard.Against<ArgumentException>(
                value < MinValue, "value can't be less than MaxValue");
            Guard.Against<ArgumentException>(
                value < 0, "value can't be less than 0");

            _MaxValue = value;
        }
    }
}

public static class Guard
{
    public static void Against<TException>(bool assertion, string message)
        where TException : Exception
    {
        if (assertion)
            throw (TException)Activator.CreateInstance(typeof(TException), message);
    }
}

So it seems to be pretty easy to handle our constraints, right? Please don’t just take this stupid example into account. Imagine more complex cases, where you have numerous constraints on your class properties (one property or more than one depending properties), which aren’t far so obvious as in this example. Can you imagine the problems which arise, when you model them implicitly?

What if we would have a mechanism to model such (depending) property constraints explicitly, thus expressing valid class states? This would have some interesting advantages. First it helps you as programmer in creating and extending your class by ensuring that the constraints are maintained. Second it works as checked documentation for your code. If other programmers are extending your class, they would be aware of the constraints. By making things explicit and code-checked, it’s ensured that your classes are in valid state at every time by watching the defined constraints. Take MinMax as an example yet again. If you or another programmer is extending the class, you are not forbidden to write _MinValue and _MaxValue directly, thus going around the „state maintainers“ in form of the setters in MinValue and MaxValue and the calls to Guard. This example is small enough to not getting confused, but in more tricky cases the class could be left easily in an inconsistent state and yield more problems. An explicit model could lead a way out of that! Third when you distribute your components to third-party users, you would yet again reveal your intent by making the constraints of the class explicit. Users would be aware of them and could easier reproduce the behavior of your components. Hence there’s a much better chance that they use your class in a proper way from the beginning.

Do we have a mechanism to model such things? First if we think about class state, perhaps the GoF State pattern comes into mind, but that doesn’t fit our needs. It doesn’t have the power to make constraints explicit and model valid class state. But we can use Code Contracts for that! Object invariants (= invariants on classes) are exactly what we need. Object invariants give us the power to model constraints on classes explicitly, check them at compile and/or runtime (using the static or dynamic checker) and moreover allow us to define them on interfaces and abstract classes! Implementing/deriving classes must maintain the defined invariants and are allowed to make them stronger (but not weaker). So how would our MinMax-class look with that? Let’s see:

public class MinMax
{
    public int MinValue { get; set; }
    public int MaxValue { get; set; }

    [ContractInvariantMethod]
    protected void ClassConstraints()
    {
        Contract.Invariant(MinValue >= 0);
        Contract.Invariant(MaxValue >= 0);
        Contract.Invariant(MinValue <= MaxValue);
    }
}

That’s really small and seems to be pretty, doesn’t it? With the ContractInvariantMethod we can declare a method that contains the invariants/constraints of the class, which must be maintained by every class method (including get/set on properties). This method and its checks are run on exit of every other class method. With Contract.Invariant() you’re able to define an invariant. It doesn’t matter if there are simple cases as here or more complex cases on depending properties (for example implications) – every boolean expression can be modelled with that.

However somebody could find some issues with this example, so let’s explain. The above code is pretty, because the constraints are outsourced to one single method (thus avoiding redundancies) and you haven’t to take care of calling this method everytime (because Code Contracts will call it for you on exit of every other method).
As first issue, callers (clients) of the MinValue.set and MaxValue.set methods don’t see directly which values are allowed, because it’s not part of the method contract (the preconditions on the setters). In this example it’s ok, because he can look at the invariants (the contract of the whole class) and see, which values are allowed. So this issue is weak here, but in other method cases you really have to duplicate invariants with preconditions, what is some kind of ugly.
Second, the static checker will not be happy with that code, because it’s aware of that you can provide some invalid value in the setters. That’s an issue of Code Contracts itself and I hope the team will come up with some further development to handle this case automatically. So this issue is weak as well.
The third issue seems to be stronger. If an invariant is broken and hence a ContractException is thrown, the wrong value will remain in the current MinMax instance, if you handle the exception outside with try/catch (MinMax is left in an invalid state). If you don’t use the object anymore, that’s no problem, but else you have no chance to go to the state before the exception was thrown, except you’re handling that on your own in the caller/client. Is this a really good issue? Again, it’s not. This issue goes away, if we look at the purpose and behavior of DbC for this case. In DbC the client is responsible for ensuring preconditions when calling a method and if it comes to properties, he has to respect the invariants, too. If the client breaks a method’s contract, then the method itself is not obligated to ensure defined behavior – it’s simply undefined. And since contracts should be compiled out from the release version (while debugging and testing has been run before), that’s no problem at all. The break of a contract means the presence of a bug. The client should not handle such a case (handle the bug) by catching the exception and then further using the object. The object should be thrown away and the client must take care to call the method in a proper way.
As you can see, there are no definite issues with this example. Fortunately for true, because including preconditions in every setter would have meant to duplicate assertions as preconditions and invariants and this would destroy the advantage of having minimal check redundancies compared with the concept of defensive programming.

This article has shown some interesting aspect of Code Contracts. Modelling constraints (on (depending) properties) and valid class states is not handled very well by programming languages and easily yields to various coding problems, since your intention isn’t made explicit and valid class state isn’t checked automatically. Code Contracts can help us in this case very well by the use of object invariants. One more time making things explicit helps you as programmer and other programmers that use or extend your components.

kick it on DotNetKicks.com

7 Gedanken zu „Code Contracts #6: Modelling constraints and state“

  1. Slightly off topic, but …
    I really think having a Square class that has Width and
    Height writable properties is a bad way to design a square class … It’s definably a bad way to design because you have two dimensions that are constrained to be the same, while mathematically speaking a square has only one defining dimension: edge length.

    What you are doing is a Rectangle that is constrained to be a square (a special case for rectangle), which breaks Liskov substitution principle.

    The Square inherits Rectangle is a classical „what you should not do“ object oriented design problem …

    The consumers of the Rectangle class expect that all inheritors of the class respect the contracts the base class imposes, and in this case the Square class, breaks the parent class imposed contracts, by narrowing the contract accepted input, anyone working polimorphically with the Rectangle class will run into issues when a Square is received.

    Classic example of Liskov substitution principle being violated:
    http://www.oodesign.com/liskov-s-substitution-principle.html

  2. Hi Pop,

    I definitely think the same way because of the same reasons you mentioned (following the LSP)! This example is not to show good code, but just to have a showcase for the problem at hand. Personally, I wouldn’t implement Square in this way,.

    Perhaps I’ll find another (better) example. If you have any ideas, please let me know 🙂

    ~ Matthias

  3. Well I think I’d go for an example that involves a EMail class:

    public class EMail {
    public string To { get … set …
    public string Subject { get … set …
    public string Body { get … set …

    [ContractInvariantMethod]
    protected void ClassConstraints()
    {
    Contract.Invariant(To != null);
    Contract.Invariant(Subject != null || Body != null);
    }
    }

  4. Hi Pop,

    Nice to see your example. I see, that you’re using the object invariants for some kind of data validation, right? I don’t know if I would use them in the same way. In general I would say: it depends 🙂

    I could imagine cases of empty EMail objects, where the invariants don’t fit. Just when I want to save them, I would validate the EMail object. Especially (besides of this EMail example) if I have depending constraints and would bind the object to an UI, perhaps I must be able to temporarily break one constraint, if I change a value, until I change the value of a depending property.

    Thus there could be problems that arise by handling data validation through invariants. It generally leads to the question: what to model through contracts and there is just few concrete information/best practices on this. Well, it really depends, but if there would be some showcases, in my opinion this would really help. First programmers and second DbC itself to get more popular.

    ~ Matthias

  5. > I see, that you’re using the object invariants for some kind of data validation

    Yes it is validation, but not runtime validation instead contractual validation (All contracts are after all data validation ( For example method parameters store data, and you validate the values of the parameters, Contracts add „data“ constraints (shape, size, etc) as opposed to only type constraints which a typed language already has)).

    > I could imagine cases of empty EMail objects

    This depends on what your API expects, I could just as well design an API that doen’t handle empty mail messages and express that as a contract, on the other hand if I’d design the API to handle empty mail messages I wouldn’t express that as a contract, but some form of runtime validation where necessary, or method contracts.

    > But should this be modelled as invariant? What’s your opinion about this?

    Not necessarily as an invariant, you could model it as a contract on the Send() Method for example which only accepts mails that have all the required fields. But the way you design it, it is a choice basically, and I think there are advantages to modeling a eMail class as invariant as it can potentially simplify the validations the code has to to in various places, and bring a bit more consistency to the API (but only if handling empty mail messages is not required)

    Anyway great series of posts, and I think the exploration of what code contracts could potentially do to make code better has just begun, and the do’s and don’ts still need to be discovered for the largest part.

  6. Hi there,

    Thanks for your loong comment. I really enjoy your comments! Discussion is the foundation of every further development.
    In my opinion, the empty EMail object can sometimes not only be necessary in cases where my API expects it. Moreover, a really important case in my opinion is handling data through any kind of UI.
    In a broader range, sometimes it would be necessary to have an empty or temporarily invalid object, thus to bring direct data binding of this object to the UI (e.g. Silverlight) to life. This would temporarily break the contract of the object, but that’s ok, since the user has recently inserted the new/empty item and is now editing it and brings it to valid state. I don’t see that this can easily be managed through contracts directly by using invariants.

    Either way, I think we are both agreeing on the „it depends“ term. It depends on the situation where to have contracts and for what to have them. If you like, I would exchange some more information with you via E-Mail (please not empty ;-)), thus to make up my mind even further. There are many questions and I think through discussion I could get a deeper insight. If you like, please send a short ping to (moved).

    Thanks, Matthias

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.