Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 The Object Constraint Language: Expressing Constraints in the UML (Most slides created by Robert B. France, Professor Department of Computer Science,

Similar presentations


Presentation on theme: "1 The Object Constraint Language: Expressing Constraints in the UML (Most slides created by Robert B. France, Professor Department of Computer Science,"— Presentation transcript:

1 1 The Object Constraint Language: Expressing Constraints in the UML (Most slides created by Robert B. France, Professor Department of Computer Science, Colorado State University. Other material from: (Source: http://www.cse.dmu.ac.uk/~aoc/teaching- notes/Contents/CSCI3007/CSCI3007OCLtutorial.pdf ) http://www.cse.dmu.ac.uk/~aoc/teaching- notes/Contents/CSCI3007/CSCI3007OCLtutorial.pdf

2 Declarative vs Imperative Programming With imperative programming, you say both what is to be done – and how it is to be done: 2 List collection = new List { 1, 2, 3, 4, 5 }; List results = new List (); foreach(var num in collection) { if (num % 2 != 0) results.Add(num); } 1.Create a result collection 2.Step through each number in the collection 3.Check the number, if it's odd, add it to the results With declarative programming, you say what is to be done – but not how it is to be done: var results = collection.Where( num => num % 2 != 0); From this link

3 3 What is OCL? The Object Constraint Language (OCL) is a declarative language for describing rules that apply to UML models OCL expressions are always associated with a UML model  OCL expressions can be associated with any model element in UML OCL can be used  to describe constraints A constraint is a restriction on one or more values of a model or system. A constraint is an expression that evaluates to true or false  as a query language Queries are expressions that evaluate to a value (true, false and other values) Can be used to define new attributes and operations

4 4 Constraints vs. Queries Examples of constraints:  The duration of a flight is the same as the difference between the arrival and departure times  The maximum number of passengers on a flight must be less than 1,001  The origin of a flight must be different than its destination Examples of queries:  Return all the departing flights from a given airport  Return all the flights departing from a given airport with a departure time after 4p.m.  Derive the arrival time by adding the duration of the flight to the departure time. Airport Flight * * departTime: Time /arrivalTime: Time duration : Interval maxNrPassengers: Integer origin desti- nation name: String arriving Flights departing Flights 1 1

5 5 Why OCL? Required age of car owners? Requirement that a person may own at most one red car - because UML is not enough!

6 6 Specifying Constraints

7 7 Different kinds of constraints Class invariant  a constraint that must always be met by all instances of the class Precondition of an operation  a constraint that must always be true BEFORE the execution of the operation Postcondition of an operation  a constraint that must always be true AFTER the execution of the operation

8 8 Specifying Constraints: Invariants

9 9 Note: self can be omitted context Flight inv capacity: maxNrPassengers <= 1000 Example: Expressing Invariants Flight capacity constraint: The maximum number of passengers that can be on a flight must be less than or equal to 1,000. context Flight inv capacity: self.maxNrPassengers <= 1000 Airport Flight * * departTime: Time /arrivalTime: Time duration : Interval maxNrPassengers: Integer origin desti- nation name: String arriving Flights departing Flights 1 1

10 10 Constraint context and self Every OCL expression is bound to a specific context.  The context is often the element that the constraint restricts The context may be denoted within the expression using the keyword ‘self’.  ‘self’ is implicit in all OCL expressions  Similar to ‘this’ in C++

11 11 Notation Constraints may be denoted within the UML model or in a separate document.  the expression: context Flight inv durationLimit: self.duration < 4  is identical to: context Flight inv: duration < 4 Flight duration: Integer inv: duration < 4  is identical to:

12 12 Example model Airport Flight Passenger Airline * * * * minAge: Integer age: Integer needsAssistance: Boolean departTime: Time /arrivalTime: Time duration : Interval maxNrPassengers: Integer origin desti- nation name: String {ordered} arriving Flights departing Flights CEO 0..1 flights passengers book(f : Flight) 0..1 airline Time difference(t:Time):Interval before(t: Time): Boolean plus(d : Interval) : Time $midnight: Time month : String day : Integer year : Integer hour : Integer minute : Integer Interval equals(i:Interval):Boolean $Interval(d,h,m : Integer) : Interval nrOfDays : Integer nrOfHours : Integer nrOfMinutes : Integer 1 1 1 1

13 13 Airport Flight Passenger Airline * * * * minAge: Integer age: Integer needsAssistance: Boolean departTime: Time /arrivalTime: Time duration : Interval maxNrPassengers: Integer origin desti- nation name: String {ordered} arriving Flights departing Flights CEO 0..1 flights passengers book(f : Flight) 0..1 airline Time difference(t:Time):Interval before(t: Time): Boolean plus(d : Interval) : Time $midnight: Time month : String day : Integer year : Integer hour : Integer minute : Integer Interval equals(i:Interval):Boolean $Interval(d,h,m : Integer) : Interval nrOfDays : Integer nrOfHours : Integer nrOfMinutes : Integer 1 1 1 1 Constraint: The difference between the depart and arrival time for a flight must be the same as its duration. context Flight inv duration: self.departTime.difference(self.arrivalTime). equals(self.duration)

14 14 Elements of an OCL expression In an OCL expression these elements may be used:  basic types: String, Boolean, Integer, Real.  classifiers from the UML model and their features attributes, and class attributes  associations from the UML model

15 15 OCL types

16 16 Precedence Rules

17 17 Some OCL Reserved Words AND ATTR ELSE ENDIF IF IMPLIES INV LET NOT OR POST PRE THEN XOR

18 18 OCL Comments Comments in OCL are written following two successive dashes “--”  -- this is a comment

19 19 Airport Flight Passenger Airline * * * * minAge: Integer age: Integer needsAssistance: Boolean departTime: Time /arrivalTime: Time duration : Interval maxNrPassengers: Integer origin desti- nation name: String {ordered} arriving Flights departing Flights CEO 0..1 flights passengers book(f : Flight) 0..1 airline Time difference(t:Time):Interval before(t: Time): Boolean plus(d : Interval) : Time $midnight: Time month : String day : Integer year : Integer hour : Integer minute : Integer Interval equals(i:Interval):Boolean $Interval(d,h,m : Integer) : Interval nrOfDays : Integer nrOfHours : Integer nrOfMinutes : Integer 1 1 1 1 context Airline inv: name.toLower = ‘usair’ context Passenger inv: age >= ((9.6 - 3.5)* 3.1).floor implies mature = true NB: A  B = ~A v B Example: OCL basic types

20 20 Associations and navigations Every association in the model is a navigation path. The context of the expression is the starting point. Role names are used to identify the navigated association.

21 21 Example: navigations The name of the airline for a flight is Delta context Flight inv: airline.name = ‘Delta’ Airport Flight * * departTime: Time /arrivalTime: Time duration : Interval maxNrPassengers: Integer origin desti- nation name: String arriving Flights departing Flights Airline name: String airline 1 The origin of a flight must be different than its destination context Flight inv: origin <> destination

22 22 Example: Invariant involving Enumerated Type The type of a flight must be the same as the type of the airplane. { context Flight inv ftype = Ftype::cargo implies Airplane.atype = Ftype::cargo inv ftype = Ftype::passenger implies Airplane.atype = Ftype:: passenger} 1 *FlightAirplane ftype : Ftypeatype : Ftype flights > Ftype cargo passenger

23 23 Association classes  Persons working with IBM have the job type “trainer” otherwise their job type is “programmer”. context Person inv: if employer.name = ‘IBM’ then Job.type = JobType::trainer else Job.type = JobType::programmer endif Person Company Job * 1 employeeemployer type : JobType name : String JobType trainer programmer

24 24 Specifying Constraints: Operation Specifications

25 25 Syntax for specifying operations context NameOfClass::operationName():returnType pre : -- some expression body : -- some expression post : some expression

26 26 Pre- and PostCondition Example A class named Account has an attribute balance and an operation overdraft() that returns true if the balance is less than 0 and false otherwise. context Account::overdraft():Boolean pre : -- none post : result = (balance < 0)

27 27 More complex operation specifications  The operation birthdayOccurs() adds 1 to the customer age. context Customer::birthdayOccurs() pre : -- none post : age = age@pre + 1age@pre  What does this describe? context Account::safeWithdraw(amt:Integer) pre : balance > amt post : balance = balance@pre - amtbalance@pre

28 28 Specifying Queries

29 29 Example model Airport Flight Passenger Airline * * * * $minAge: Integer age: Integer needsAssistance: Boolean departTime: Time /arrivalTime: Time duration : Interval maxNrPassengers: Integer origin desti- nation name: String {ordered} arriving Flights departing Flights CEO 0..1 flights passengers book(f : Flight) 0..1 airline Time difference(t:Time):Interval before(t: Time): Boolean plus(d : Interval) : Time $midnight: Time month : String day : Integer year : Integer hour : Integer minute : Integer Interval equals(i:Interval):Boolean $Interval(d,h,m : Integer) : Interval nrOfDays : Integer nrOfHours : Integer nrOfMinutes : Integer 1 1 1 1

30 30 Derived Attribute & Initial Value Example Defining derived attributes context Flight::arrivalTime:Time derive:departTime.plus(duration) Defining initial attribute value context Flight::maxNrPassengers:Integer init: 100 Defining initial association end value context Flight::passengers:Set(Passenger) init: Set{}

31 31 Query operation examples Return all the departing flights from a given airport context Airport::departures():Set(Flight) body: result=departingFlights Return all the airports served by an airline context Airline::served():Set(Airport) body: result=flights.destination->asSet() Airline name: String Airport Flight * * * departTime: Time /arrivalTime: Time duration : Interval maxNrPassengers: Integer origin desti- nation name: String arriving Flights departing Flights flights airline 1 1 1 1

32 32 More Advanced OCL Expressions

33 33 Significance of collections in OCL Most navigations return collections rather than single elements 10..*FlightAirplane type : enum of cargo, passenger type : enum of cargo, passenger flights

34 34 Subtypes of Collection 1. Set: each element occurs only once (Non-ordered, unique) 2. OrderedSet: a set with ordered elements. 3. Bag: elements may be present more than once(non-ordered, non- unique) 4. Sequence: a bag with ordered elements (ordered, non-unique)

35 35 Subtypes of Collection Airline name: String Airport Flight * * * departTime: Time /arrivalTime: Time duration : Interval maxNrPassengers: Integer origin desti- nation name: String arriving Flights departing Flights flights airline 1 1 1 1 Passenger * $minAge: Integer age: Integer needsAssistance: Boolean {ordered} passengers book(f : Flight) Set: arrivingFlights - from the context Airport Non-ordered, unique Bag: arrivingFlights.duration - from the context Airport Non-ordered, non-unique Sequence: passengers - from the context Flight Ordered, non-unique

36 36 Collection operations OCL has a great number of predefined operations on the collection types. Syntax:  collection -> operation Use of the “->” (arrow) operator instead of the “.” (dot) operator

37 37 The collect operation Syntax: collection->collect(elem : T | expr) collection->collect(elem | expr) collection->collect(expr) The collect operation results in the collection of the values resulting from evaluating expr for all elements in the collection Shorthand often trips people up. Be Careful!

38 38 Example: collect operation context Airport inv: self.arrivingFlights -> collect(airLine) ->notEmpty airp1 airp2 f1 f2 f3 f4 f5 airline1 airline2 airline3 departing flights arriving flights All arriving flights must be associated with an airline

39 39 The select operation Syntax: collection->select(elem : T | expression) collection->select(elem | expression) collection->select(expression) The select operation results in the subset of all elements for which expression is true

40 40 Example: select operation context Airport inv: self.departingFlights->select(duration notEmpty departing flights arriving flights airp1 airp2 airline1 airline2 airline3 f5 duration = 2 f1 duration = 2 f4 duration = 5 f2 duration = 5 f3 duration = 3 There must be at least one departing flight whose duration is less than 4

41 41 The forAll operation Syntax:  collection->forAll(elem : T | expr)  collection->forAll(elem | expr)  collection->forAll(expr) The forAll operation results in true if expr is true for all elements of the collection

42 42 Example: forAll operation context Airport inv: self.departingFlights->forAll(departTime.hour>6) departing flights arriving flights airp1 airp2 airline1 airline2 airline3 f5 depart = 8 f1 depart = 7 f4 depart = 9 f2 depart = 5 f3 depart = 8 All departing flights must leave after 6

43 43 The exists operation Syntax: collection->exists(elem : T | expr) collection->exists(elem | expr) collection->exists(expr) The exists operation results in true if there is at least one element in the collection for which the expression expr is true.

44 44 Example: exists operation context Airport inv: self.departingFlights->exists(departTime.hour<6) departing flights arriving flights airp1 airp2 airline1 airline2 airline3 f5 depart = 8 f1 depart = 7 f4 depart = 9 f2 depart = 5 f3 depart = 8

45 45 Other collection operations isEmpty: true if collection has no elements notEmpty: true if collection has at least one element size: number of elements in collection count(elem): number of occurences of elem in collection includes(elem): true if elem is in collection excludes(elem): true if elem is not in collection includesAll(coll): true if all elements of coll are in collection

46 46 Examples A vehicle owner must be at least 18 years old.: context Vehicle inv: self.owner. age >= 18

47 47 A car owner must be at least 18 years old.: context Car inv: self.owner. age >= 18 Examples

48 48 Nobody has more than 3 vehicles: context Person inv: self.fleet->size <= 3 Examples

49 49 All vehicles of a person are black: context Person inv: fleet->forAll(v | v.colour = #black) Examples

50 50 Nobody has more than 3 red vehicles: context Person inv: fleet->select(v | v.colour = #red)->size <= 3 Examples

51 51 context Person inv: age forAll(v | not v.oclIsKindOf(Car)) A person younger than 18 owns no cars.. Examples

52 52 There is a red car in somebody’s fleet: context Person inv: fleet->select(v | v.colour = #red)->notEmpty context Car inv: Car.allInstances()->exists(c | c.colour=#red) Examples

53 53 Examples: pre-post conditions If setAge(... ) is called with a non-negative argument then the argument becomes the new value of the attribute age. context Person::setAge(newAge:int) pre: newAge >= 0 post: age = newAge

54 54 Examples: pre-post conditions Calling birthday() increments the age of a person by 1. context Person::birthday() post: age = age@pre + 1

55 55 Examples: pre-post conditions Calling getName() delivers the value of the attribute name. context Person::getName() post: result = name

56 56 Local variables The let construct defines variables local to one constraint: Let var : Type = in Example: context Airport inv: Let supportedAirlines : Set (Airline) = self.arrivingFlights -> collect(airLine) in (supportedAirlines ->notEmpty) and (supportedAirlines ->size < 500)

57 57 Iterate The iterate operation for collections is the most generic and complex building block. collection->iterate(elem : Type; answer : Type = | )

58 58 Iterate example Example iterate: context Airline inv: flights->select(maxNrPassengers > 150)->notEmpty Is identical to: context Airline inv: flights->iterate (f : Flight; answer : Set(Flight) = Set{ } | if f.maxNrPassengers > 150 then answer->including(f) else answer endif )->notEmpty

59 59 Inheritance of constraints Guiding principle Liskov’s Substitution Principle (LSP):  “Whenever an instance of a class is expected, one can always substitute an instance of any of its subclasses.”

60 60 Inheritance of constraints Consequences of LSP for invariants:  An invariant is always inherited by each subclass.  Subclasses may strengthen the invariant. Consequences of LSP for preconditions and postconditions:  A precondition may be weakened (contravariance) A method in a subclass can weaken the precondition of a method in the superclass. That means the subclass method can accept a wider range of values. So data that is valid in the subclass may be invalid in the superclass.  A postcondition may be strengthened (covariance) A subclass’s method can strengthen the postcondition (but it cannot weaken it): a subclass‘s method can return a subset of the values returned by the method it overrides.

61 Weakening Preconditions abstract class Payment { /** * @pre amt >= 0 */ public void setPaymentAmount(int amt) {…} } 61 class CreditCardPayment extends Payment { /** * @pre true */ public void setPaymentAmount(int amt) {…} } class CashPayment extends Payment { … }

62 Why does it not make sense to strengthen the precondition? Suppose we set the precondition on the setPaymentAmount of CreditCardPayment to be: @pre amt >= 25 Client should be able to do: Payment p; // substitute CashPayment for Payment p = new CashPayment(); p.setPaymentAmount( 5 ); // substitute CreditCardPayment for Payment p = new CreditCardPayment(); p.setPaymentAmount( 5 ); // oops! 62 Example from: http://www.ugrad.cs.ubc.ca/~cs211/notes/L07-InheritanceGoodBad-4up.pdf

63 Why does it not make sense to weaken the postcondition? Suppose the client writes code based on the postcondition of the superclass. That client code could break if we substitute a superclass object with an instance of one of its subclasses if the subclass' method has a weaker postcondition.  client writes code assuming that a method returns a value that is positive  subclass overrides method to return *any* value (so postcondition is weakened)  client code is going to break if a negative value is returned. 63

64 64 Exercise: The Stack Data Structure  push(Element elm) – add elm to top of stack  pop() – removes and returns element on top of stack  isEmpty() – returns true if stack has no elements  top() – returns element on top of stack  previous(Element elm) – returns the element inserted on the stack immediately before elm.  isFull() – returns true if stack has maximum number of elements Assuming top, previous and isFull are already specified, specify pre and post conditions for the other operations. Stack push(Element elm) pop():Element isEmpty():Boolean top(): Element previous(Element elm):Element isFull():Boolean

65 65 Summary and OCL Tips OCL invariants allow you to  model more precisely  remain implementation independent OCL pre- and postconditions allow you to  specify contracts (design by contract)  specify interfaces of components more precisely OCL usage tips  keep constraints simple  always combine natural language with OCL  use a tool to check your OCL

66 Further Resources for OCL The Object Constraint Language  ISBN 0-201-37940-6

67 67 Conclusion Finally! !

68 Questions: operational invariants - ANSWERS Context Stack::isEmpty()  Pre: none  Post: result = (^top() = null)

69 Questions: operational invariants - ANSWERS Context Stack::push(Element elm)  pre: ^isFull() = false  post: ^top() = elm Context Stack::pop()  Pre: ^isEmpty() = false and elm = ^top()  Post: result = elm and ^top() = previous(elm@pre)


Download ppt "1 The Object Constraint Language: Expressing Constraints in the UML (Most slides created by Robert B. France, Professor Department of Computer Science,"

Similar presentations


Ads by Google