Section A.6. Types of Constraints


A.6. Types of Constraints

There are three types of constraints:


Invariants

An invariant is a constraint that must always be trueotherwise the system is in an invalid state. Invariants are defined on class attributes. For example, in Figure A-4, the baseCost attribute of AccountFee must always be greater than or equal to zero.


Preconditions

A precondition is a constraint that is defined on a method and is checked before the method executes. Preconditions are frequently used to validate input parameters to a method.


Postconditions

A postcondition is also defined on a method and is checked after the method executes. Postconditions are frequently used to describe how values were changed by a method.

Previous examples in this chapter focused on invariants, but all three constraint types can be expressed in your UML diagrams or related documentation. The following examples will show how to provide preconditions and postconditions for the method incrementRating. The reference class diagram is shown in Figure A-5.

Figure A-5. We'll provide preconditions and postconditions for the incrementRating method


Suppose incrementRating will increment the value rating by the value amount. We want to first specify a precondition that amount is less than a maximum legal amount, say 100, and a postcondition ensuring that rating has been incremented by amount. To write these preconditions and postconditions, you first specify the context and then the constraints.

 context BlogEntry::incrementRating(amount: int) : void pre: amount <= 100 post: rating = rating@pre + amount 

Notice the @pre directive: rating@pre is the value of rating before the method executes. You can use the @pre notation on methods too:

 context BlogEntry::incrementRating(amount: int) : void pre: amount <= 100 post: getRating(  ) = getRating@pre(  ) + amount 

Invariants, preconditions, and postconditions are part of an approach known as "Design by Contract," developed by Bertrand Meyer. "Design by Contract" attempts to make more reliable code by establishing a contract between a class and its clients. A class's contract tells its clients that if they call its methods with valid values, then they will receive a valid value in response. A contract also establishes invariants on a class, meaning that the class's attributes will never violate certain constraints.

If you're wondering why you haven't encountered invariants, preconditions, and postconditions in your code, note that support for Design by Contract differs per programming language. "Design by Contract" is built into the Eiffel programming language, which was also developed by Bertrand Meyer. Eiffel has keywords for invariants, preconditions, and postconditions, and an exception is thrown if any of these constraints are violated. With other languages, you have to either implement constraint handing yourself or use a package such as iContract for Java. iContract is a preprocessor with doc-style tags to specify invariants, preconditions, and postconditions. iContract also throws an exception if a constraint is violated.




Learning UML 2.0
Learning UML 2.0
ISBN: 0596009828
EAN: 2147483647
Year: 2007
Pages: 175

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net