You can think of the class invariant as a health criterion, which must be fulfilled by all objects in between operations. As a precondition of every public operation of the class, it can therefore be assumed that the class invariant holds. In addition, it can be assumed as a postcondition of every public operation that the class invariant holds. In this sense, the class invariant serves as a general strengthening of both the precondition and the postcondition of public operations in the class. The effective precondition is the formulated precondition in conjunction with the class invariant. Similarly, the effective postcondition is the formulated postcondition in conjunction with the class invariant.
public class Server
{
// other code ommited
public Output Foo(Input cmdIn)
{
...
return cmdOut;
}
}
public class Caller
{
// other code ommited
/* calls Server.Foo */
public void Call()
{...}
}
public class Input
{
// other code ommited
public int Length
{...}
}
public class Output
{
// other code ommited
public int Length
{...}
}
1. If class invariant is defined on Server
class:
a) Preconditions are typically formulated in terms of the formal parameters of the called operation, so how can class invariant strengthen method's ( Foo
's ) preconditions?
b) Postcondition is formulated in terms of called method's return value, so how can class invariant strengthen method's ( Foo
's ) postconditions?
2. Can class invariant defined on Caller
class in any way strengthen Foo
's preconditions or postconditions?
3. If class invariant is defined on Foo
's cmdIn
parameter:
a) If precondition on Foo
states that cmdIn.Length
is within range 1-20
, but one of class invariants defined on Input
states that Input.Length
should be within range 2-19
, then Foo
's precondition was indeed strenghten?
b) Isn't the logic in a) a bit flawed, since if class invariant already states that Input.Length
should be within range 2-19
, isn't it then an error for Foo
to define a precondition which isn't always be true
( cmdIn.Length
can't hold values 1
or 20
)
c) But if class invariant defined on Input
states that Input.Length
should be within range 0-100
, then Foo
's precondition isn't strengthen?
d) Can class invariants defined on cmdIn
also somehow strengthen Foo
's postcondition?
4. If class invariant is defined on Foo
's return value
a) If postcondition on Foo
states that cmdOut.Length
is within range 1-20
, but one of class invariants defined on Output
states that Output.Length
should be within range 2-19
, then Foo
's postcondition was indeed strengthen?
b) But if invariant defined on Output
states that Output.Length
should be within range 0-100
, then Foo
's postcondition wasn't strengthen?
c) Can class invariants defined on Output
also somehow strengthen Foo
's precondition?
5. But I get the impression that quoted article meant to say that just by having a class invariant ( and even if this invariant doesn't in any way operate ( directly or indirectly ) on Foo
's parameters and/or return value, it would still strengthen Foo
's preconditions and postcondition? If that's what article is actually implying, how is that possible?
thanks