Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 8, Object Design: Object Constraint Language

Similar presentations


Presentation on theme: "Chapter 8, Object Design: Object Constraint Language"— Presentation transcript:

1 Chapter 8, Object Design: Object Constraint Language

2 Outline of the Lecture OCL Simple predicates Preconditions
Postconditions Contracts Sets, Bags, and Sequences

3 OCL: Object Constraint Language
Formal language for expressing constraints over a set of objects and their attributes in a model Used to write constraints that cannot otherwise be expressed in a diagram Developed by IBM Originally part of the UML standard OCL can now be used with any MOF meta-model OCL is used in the QVT specification for model transformations (Queries-Views-Transformations specification) Declarative No side effects, No control flow Based on Sets and Multi Sets.

4 OCL Basic Concepts OCL expressions Return True or False
Are evaluated in a specified context, either a class or an operation All constraints apply to all instances.

5 OCL Simple Predicates Example: context Tournament inv:
self.getMaxNumPlayers() > 0 In English: “The maximum number of players in any tournament should be a postive number.” Notes: “self” denotes all instances of “Tournament” OCL uses the same dot notation as Java.

6 OCL Preconditions Example: context Tournament::acceptPlayer(p) pre:
not self.isPlayerAccepted(p) In English: “The acceptPlayer(p) operation can only be invoked if player p has not yet been accepted in the tournament.” Notes: The context of a precondition is an operation isPlayerAccepted(p) is an operation defined by the class Tournament.

7 OCL Postconditions Example: context Tournament::acceptPlayer(p) post:
self.getNumPlayers() = + 1 In English: “The number of accepted player in a tournament increases by one after the completion of acceptPlayer()” Notes: denotes the state of the tournament before the invocation of the operation. Self denotes the state of the tournament after the completion of the operation.

8 OCL Contract for acceptPlayer() in Tournament
context Tournament::acceptPlayer(p) pre: not isPlayerAccepted(p) getNumPlayers() < getMaxNumPlayers() context Tournament::acceptPlayer(p) post: isPlayerAccepted(p) getNumPlayers() + 1

9 OCL Contract for removePlayer() in Tournament
context Tournament::removePlayer(p) pre: isPlayerAccepted(p) context Tournament::removePlayer(p) post: not isPlayerAccepted(p) getNumPlayers() - 1

10 Java Implementation of Tournament class (Contract as a set of JavaDoc comments)
public class Tournament { /** The maximum number of players  * is positive at all times. maxNumPlayers > 0  */ private int maxNumPlayers; /** The players List contains    * references to Players who are  * are registered with the  * Tournament. */ private List players; /** Returns the current number of  * players in the tournament. */ public int getNumPlayers() {…} /** Returns the maximum number of  * players in the tournament. */ public int getMaxNumPlayers() {…} /** The acceptPlayer() operation  * assumes that the specified  * player has not been accepted * in the Tournament yet. !isPlayerAccepted(p) getNumPlayers()<maxNumPlayers isPlayerAccepted(p) getNumPlayers() = * @pre.getNumPlayers() + 1 */ public void acceptPlayer (Player p) {…} /** The removePlayer() operation * assumes that the specified player * is currently in the Tournament. isPlayerAccepted(p) !isPlayerAccepted(p) getNumPlayers() = * @pre.getNumPlayers() - 1 */ public void removePlayer(Player p) {…} } As we can see, the OCL contract is now written as a set of JavaDoc comments. The specific OCL Javdoc could be read to a verification system or a runtime debugging system That inserts specific code as a result of these tags to ensure the validity of the predicates (slows down the computation quite a bit, verification would be better, but currently not state of the art for large complex systems.

11 Constraints can involve more than one class
How do we specify constraints on on a group of classes? The value of this expression is the set of objects on the other side of the role name association. If the multiplicity of the association-end has a maximum of one ("0..1" or "1"), then the value of this expression is an object. If the multiplicity is "0..1" then the result is an empty set if there is no object, otherwise it is the unique object. Navigation expression generate Collections of objects. By default, navigation will result in a Set. When the association on the Class Diagram is adorned with {ordered}, the navigation results in a Sequence. Collections, like Sets, Bags and Sequences, are predefined types in OCL. They have a large number of predefined operations on them. collection->operation(arguments) Starting from a specific class in the UML class diagram, we navigate the associations in the class diagram to refer to the other classes and their properties (attributes and Operations).

12 Example from ARENA: League, Tournament and Player
players * tournaments {ordered} Tournament +start:Date +end:Date +acceptPlayer(p:Player) League +getActivePlayers() Player +name:String + String Constraints: A Tournament’s planned duration must be under one week. Players can be accepted in a Tournament only if they are already registered with the corresponding League. The number of active Players in a League are those that have taken part in at least one Tournament of the League. To better understand these constraints, we instantiate the class diagram for a specific group of instances 2 Leagues 5 Players 2 Tournaments

13 Instance Diagram: 2 Leagues
, 5 Players, 2 Tournaments tttExpert:League chessNovice:League alice:Player bob:Player marc:Player joe:Player Xmas:Tournament start=Dec 23 end= Dec 25 zoe:Player winter:Tournament start=Jan 12 end= Jan 14

14 3 Types of Navigation through a Class Diagram
1. Local attribute 2. Directly related class 3. Indirectly related class Tournament start:Date end:Date League Player * Tournament League * Player Within the context of one class, e.g. tournamen, I can construct a predicate out of the attributes of this class. Given a certain context, say League, I can specify a constraint, that involves methods and attributes of a directly associated class, say Player. Given a certain context, say League, I can specify constraints on classes that are not directly reachable via a neighbor association, but via a couple of associations. Any constraint for an arbitrary UML class diagram can be specified using only a combination of these 3 navigation types!

15 Specifying the Model Constraints in OCL
Local attribute navigation players * tournaments {ordered} Tournament +start:Date +end:Date +acceptPlayer(p:Player) League +getActivePlayers() Player +name:String + String context Tournament inv: end - start <= 7 Directly related class navigation context Tournament::acceptPlayer(p) pre: league.players->includes(p)

16 OCL-Collection The OCL-Type Collection is the generic superclass of a collection of objects of Type T Subclasses of Collection are Set: Set in the mathematical sense. Every element can appear only once Bag: A collection, in which elements can appear more than once (also called multiset) Sequence: A multiset, in which the elements are ordered Example for Collections: Set(Integer): a set of integer numbers Bag(Person): a multiset of persons Sequence(Customer): a sequence of customers The element type T is the type of a primitive value (Integer, String, Boolean) or the type of an object (e.g. Person, Tournament).

17 OCL Sets, Bags and Sequences
Sets, Bags and Sequences are predefined in OCL and subtypes of Collection. OCL offers a large number of predefined operations on collections. They are all of the form: collection->operation(arguments)

18 OCL-Operations for OCL-Collections (1)
size: Integer Number of elements in the collection includes(o:OclAny): Boolean True, if the element o is in the collection count(o:OclAny): Integer Counts how many times an element is contained in the collection isEmpty: Boolean True, if the collection is empty notEmpty: Boolean True, if the collection is not empty The OCL-Type OclAny is the most general OCL-Type. OCL-Operations to determine the properties of a collection:

19 OCL-Operations for OCL-Collections(2)
union(c1:Collection) Union with collection c1 intersection(c2:Collection) Intersection with Collection c2 (contains only elements, which appear in the collection as well as in collection c2 auftreten) including(o:OclAny) Collection containing all elements of the Collection and element o select(expr:OclExpression) Subset of all elements of the collection, for which the OCL-expression expr is true. Operations to generate new collections (Result is again a collection):

20 How do we get OCL-Collections?
A collection can be generated by explicitly enumerating the elements from the UML model A collection can be generated by navigating along one or more 1-N associations in the UML model Navigation along a single 1:n association yields a Set Navigation along a couple of 1:n associations yields a Bag (Multiset) Navigation along a single 1:n association labeled with the constraint {ordered} yields a Sequence Of course, also by calling an OCL collection operation on an OCL collection

21 Loyalty Program Problem Statement
A customer loyalty program (LoyaltyProgram) associated many program partners (ProgramPartner) that offer different kinds of bonuses called services (Service) with customers. A customer (Customer) can enter a loyalty program by filling out a form and obtainining a customer card (CustomerCard). A customer can enter many loyalty programs. A customer can have multiple cards. A customer card is uniquely associated with a single customer Each customer card is associated with a loyalty account (LoyaltyAccount) and characterized by a service level (ServiceLevel). The loyalty account allows customers to save bonus points in their account. The basic service level is silver. Customers who make a lot of transactions get a higher level of service, gold or platinum. Based on the service level and the saved bonus points, customers can “buy” services from a program partner for a specific number of points. So, earning and Buying points are types of transactions (Transaction) on a loyalty account involving services provided by the program partners. They are always only performed for a single customer card. The objects of class Customer represent the persons who have entered the program. Source: Jos Warmer& Anneke Kleppe, The Object Constraint Language: Getting your models ready for MDA, 2nd edition, Addison Wesley, 2003.

22 1..* 1..* 1 0..* 1 1 {ordered} 1..* 1 1 0..1 0..* 1 1 0..* account 1
LoyaltyProgram Customer 1..* name: String title:String isMale: Boolean dateOfBirth: Date 0..* 0..* 1..* partners enroll(c:Customer) programs ProgramPartner 1 numberOfCustomers: Integer 0..* Membership age(): Integer partner 1 1 {ordered} 1..* 1 actualLevel 1 owner 0..1 ServiceLevel 0..* card LoyaltyAccount card name: String CustomerCard deliveredServices 0..* 1 points: Integer 1 level valid: Boolean validForm: Date goodThru: Date color: enum{silver, gold} printedName: String earn(i: Integer) burn(i: Integer) isEmpty(): Boolean An association class is used to model an association as a class. Association classes often occur in many-to-one and many-to-many associations where the association itself has attributes and operations, which cannot be easily associated with either class. As an example, consider a many-to-many association between classes LoyaltyProgram and Customer. The association has properties such as name of the service level, accumulated points, color of the card, points. Rather than trying to fold the attributes into one of the classes in the association (either LoyaltyProgram or Customer), it is more elegant, to model the association as an association class Membership with attributes such as service level name, points in the account and customer card color. In fact, notice that because these abstractions are modeled themselves as classes (ServiceLevel, LoyaltyAccount, CustomerCard) the association class Memmbership is associated with these three classes! An association class is rendered by a dashed line from the association to the class rectangle. Each link in the association is an object of the association class. An association class is essentially a class attached to an association; the association itself is modeled as a class or even – as in our case – as a class membership which as associations to 3 other classes (ServiceLevel, LoyaltyAccount, CustomerCard). Here are some pointers to consider when modeling with association The name of the association is usually omitted since it is considered to be the same as that of the attached class. Distinguish between the use of an association class as a modeling technique and the implementation of the association class. There can be several ways to implement an association class. Service 0..* condition: Boolean pointsEarned: Integer pointsBurned: Integer description: String availableServices account 1 transactions 0..* Transaction generatedBy 1 card points: Integer date:Date 1 0..* 0..* transactions Date transactions program(): LoyaltyProgram now: Date isBefore(t:Date): Boolean isAfter(t:Date): Boolean =(t:Date): Boolean Burning Earning 22

23 card denotes a set of customercards
Navigation through a 1-to-n-Association (Directly related class navigation) Example: A Customer should not have more than 4 cards context Customer inv: card->size <= 4 Alternative writing style Customer name: String titel: age: Integer birthday: Date getage(): Customer valid: Boolean validSince: expires: color: enum { silver, gold} printedName : customerCard owner card * card denotes a set of customercards

24 OCL Constraints on the Loyalty Account
class invariant points: Integer { points >= 0 } earn(i: Integer) burn(i: Integer) isEmpty(): Boolean <<precondition>> i >= 0 <<precondition>> points >= i and i >= 0 precondition for burn operation <<postcondition>> points = + i <<postcondition>> points = - i <<postcondition>> result = (points=0) postcondition for burn operation

25 Navigation through a constrained Association
Navigation through an association with the constraint {ordered} yields a sequence Problem Statement: The number of service levels must be 2 LoyaltyProgram servicelevel->size = 2 LoyaltyProgram A bonus program should offer two levels. The number of levels in a bonus program should be two. enroll(k: Customer) servicelevel denotes a sequence {ordered} * ServiceLevel name: String

26 Operations on OCL-Type Sequence
first: T The first element of a sequence last: T The last element of a sequence at(index:Integer): T Element index in the sequence Problemstatement: The first level in the loyalty program has the name 'Silver‘. The highest level you can reach is ‘Platinum'.“ OCL-Invariants: LoyaltyProgram: servicelevel->first.name = "Silver“ servicelevel->last.name = “Platinum“ LoyaltyProgram enroll(c:Customer) 1 {ordered} 1..* ServiceLevel name: String

27 Navigation through several 1:n-Associations
nrcustomer: Integer ProgramPartner name: String titel: age: Dateof Birth: Date age(): Customer 1..* enroll(k: Customer) LoyaltyProgram programs * .* Question to the students: Is this english description correct? The number of customers registered by a programPartner must be equal to the number of customers that belong to a bonus program offered by the programPartner Problem Statement: “The number of customers registered by a program partner must be equal to the number of customers belonging to a loyalty program offered by the program partner” Context ProgramPartner inv nrcustomer = loyaltyprogram->customer->size loyaltyprogram denotes a set of objects of type LoyaltyProgram customer denotes a multiset of objects of type Customer ProgramPartner nrcustomer = loyaltyprogram->customer->size

28 Conversion between OCL-Collections
OCL offers operations to convert OCL-Collections: asSet Transforms a multiset or sequence into a set asBag transforms a set or sequence into a multiset asSequence transforms a set or multiset into a sequence.

29 Example of a Conversion
programPartner nrcustomer = loyaltyprogram->customer->size Caution: This OCL expression may contain a specific customer several times! We can get the number of unique customers as follows: nrcustomer = loyaltyprogram->customer->asSet->size nrcustomer: Integer programPartner name: String titel: age: dateOfBirth: Date age(): Customer 1..* entroll(k: Customer) LoyaltyProgram programs * .*

30 Evaluating OCL Expressions when navigating a UML Class Diagram
The value of any OCL expression is an object or a collection of objects Navigating an association-end with multiplicity 1 Result: a single object Navigating an association-end with multiplicity 0..1 Empty set, if there is no object, otherwise a single object Navigating several association-ends with multiplicity n Result: A collection of objects If the association is {ordered}, the navigation result is a OCL sequence Multiple “1-n” associations result in a OCL multiset (bag) Otherwise the navigation result is a OCL set. The value of an OCL expression is an object or a collection of objects. We obtain these objects by navigating through the associations of the class diagram If the multiplicity of the association-end is 1, the value of the OCL expression is a single object. If the multiplicity is 0..1, the result is an empty set if there is no object, otherwise a single object.

31 Another Navigation Example: A Mortgage System

32 Another Navigation Example: A Mortgage System
Constraints (in the Problem Statement): “A person can have a mortgage only on the house owned by that person” 2. “The start date of a mortgage must before its end date.”

33 Formal Specification of the Constraints in OCL
“A person can have a mortgage only on the house owned by that person” 2. “The start date of a mortgage must before its end date.” context Mortgage inv: security.owner = borrower context Mortgage inv: startDate < endDate

34 Predicate Calculus vs First-Order Logic
So far, we have presented OCL as propositional logic Propositional logic consists of well formed formulas (wffs) constructed of a set of primitive symbols (true, false), letters (a, b, x,y,...), and a set of operators (and ∧ , or ∨, not ∼ ...) OCL is actually a first order logic over the domain of OCL collections Any first order logic also supports quantification Existential quantification(in symbolic logic: ∃, in OCL: exists) The OCL exists operator takes a boolean expression as parameter. It evaluates to true if the parameter is true for at least one element of the OCLcollection Universal quantification (in symbolic logic:∀, in OCL: forAll) The OCL forAll operator takes a boolean expression as parameter. It evaluates to true if it is true for all the elements of the OCLcollection.

35 ForAll Example (From Arena)
Player players * matches tournaments Match -start:Date -end:Date Tournament +start:Date +end:Date +acceptPlayer(p:Player) Date now: Date isBefore(t:Date): Boolean isAfter(t:Date): Boolean equals(t:Date): Boolean Problem Statement: “All Matches in a Tournament must occur within the time frame of the Tournament” context Tournament inv: matches->forAll(m| m.start.isAfter(self.start) and m.start.isBefore(self.end))

36 Exists Example Player players * matches tournaments Match -start:Date -end:Date Tournament +start:Date +end:Date +acceptPlayer(p:Player) Date now: Date isBefore(t:Date): Boolean isAfter(t:Date): Boolean =(t:Date): Boolean Problem Statement: “Each Tournament conducts at least one Match on the first day of the Tournament” context Tournament inv: matches->exists(m:Match| m.start.equals(start))

37 Readings about OCL and Tools
J.B. Warmer, A.G. Kleppe The Object Constraint Language: Getting your Models ready for MDA, Addison-Wesley, 2nd edition, 2003 The Dresden OCL Toolkit The Dresden OCL Toolkit for Eclipse

38 Readings about Contracts
B. Meyer Object-Oriented Software Construction, 2nd edition, Prentice Hall, 1997. B. Meyer, Design by Contract: The Lesson of Ariane, Computer, IEEE, Vol. 30, No. 2, pp , January C. A. R. Hoare, An axiomatic basis for computer programming. Communications of the ACM, 12(10): , October (Good starting point for Hoare logic: Berard discusses the similarities and differences between Abstraction, Information hiding and encapsulation. Meyers article on Lessons of Ariane is an interesting reading on the Ariane 5 Failure in the context of design by contract. The basis for OCL was laid in the late 1960s by Tony Hoard. A good online starting point for Hoare is actually the Wikipedia:

39 Summary Constraints are predicates (often boolean expressions) on UML model elements Contracts are constraints on a class that enable class users, implementors and extenders to share the same assumption about the class (“Design by contract”) OCL is the example of a formal language that allows us to express constraints on UML models The names of the model elements in the UML model are used in the formulation of the OCL predicates The context definition of an OCL expression specifies the model entity for which the OCL expression is defined. Complicated constraints involving more than one class, attribute or operation can be formulated by using 3 basic navigation types: Local attribute navigation, directly related class navigation, indirectly related class navigation. The OCL is an interesting concept but it hasn’t been adopted by the industry. It still shows no signs of being adopted any time soon, but in my opinion it worth the effort to learn.

40 Backup and Additional Slides

41 Additional Constraints on this Model
A Tournament’s planned duration must be under one week. Players can be accepted in a Tournament only if they are already registered with the corresponding League. The number of active Players in a League are those that have taken part in at least one Tournament of the League.

42 Additional Constraints on this Model
A Tournament’s planned duration must be under one week. Players can be accepted in a Tournament only if they are already registered with the corresponding League. The number of active Players in a League are those that have taken part in at least one Tournament of the League.

43 Additional Constraints on this Model
A Tournament’s planned duration must be under one week. Players can be accepted in a Tournament only if they are already registered with the corresponding League. The number of active Players in a League are those that have taken part in at least one Tournament of the League.

44 ForAll Example (2) Player players * matches tournaments Match -start:Date -end:Date Tournament +start:Date +end:Date +acceptPlayer(p:Player) English: “A match can only involve players who are accepted in the tournament” context Match inv: players->forAll(p| p.tournaments->exists(t| t.matches->includes(self))) context Match inv: players.tournaments.matches.includes(self)


Download ppt "Chapter 8, Object Design: Object Constraint Language"

Similar presentations


Ads by Google