A.6. Types of ConstraintsThere are three types of constraints:
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 methodSuppose 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. |