The Object Constraint Language: Getting Your Models Ready for MDA (2nd Edition)
The advantage of using inheritance is that an object using the superclass interface need not know about the subclasses. However, sometimes you explicitly want to mention the subclasses. In the R&L example, the program partners want to limit the number of bonus points they give away; they have set a maximum of 10,000 points to be earned using services of one partner. The following invariant sums all the points of all transactions for a partner. It does not specify our intent, however, because it does not differentiate between burning and earning transactions: context ProgramPartner inv totalPoints: deliveredServices.transactions.points->sum() < 10,000 To determine the subclass to which an element of this collection of transactions belongs, we use the standard operation oclIsTypeOf, which takes a class, datatype, component, or interface name as parameter. To retrieve from the collection all instances of this subclass, we use the select operation. We use the collect operation to retrieve from the collection of earning transactions a collection of points. These are the points that are summed by the operation sum and compared with the given maximum. Therefore, the correct invariant would be as follows : context ProgramPartner inv totalPointsEarning: deliveredServices.transactions ->select( oclIsTypeOf( Earning ) ).points->sum() < 10,000 |