Вы находитесь на странице: 1из 24

Object Constraint Language (OCL)

A UML diagram (e.g., a class diagram) does not provide all relevants aspects of a specication It is necessary to describe additional constraints about the objects in the model Constraints specify invariant conditions that must hold for the system being modeled Constraints are often described in natural language and this always result in ambiguities Traditional formal languages allow to write unambiguous constraints, but they are dicult for the average system modeler OCL: Formal language used to express constraints, that remains easy to read and write

Object Constraint Language (OCL)


Pure expression language: expressions do not have side eet 3 when an OCL expression is evaluated, it returns a value 3 its evaluation cannot alter the state of the corresponding executing system 3 an OCL expression can be used to specify a state change (e.g., in a postcondition) Not a programming language 3 it is not possible to write program logic or ow of control in OCL 3 cannot be used to invoke processes or activate non-query operations Typed language: each expression has a type 3 well-formed expressions must obey the type conformance rules of OCL 3 each classier dened in a UML model represents a distinct OCL type 3 OCL includes a set of supplementary predened types The evaluation of an OCL expression is instantaneous 3 the state of objects in a model cannot change during evaluation 2

Object Constraint Language, May 12, 2008 1

Where to Use OCL


To specify invariants on classes and types in the class model To specify type invariants for stereotypes To describe pre- and post-conditions on operations and methods To describe guards As a navigation language To specify constraints on operations OCL is used to specify the well-formedness rules of the UML metamodel

Basic Values and Types


A number of basic types are predened in OCL Examples of basic types and their values Type Boolean Integer Real String Type Boolean Integer Real String Values true, false 1, -5, 2564, ... 1.5, 3.14, ... To be or not to be, ...

A number of operations are dened on the predened types Operations and, or , xor, not, implies, if-then-else-endif +, -, *, /, abs, div, mod, max, min +, -, *, /, abs, floor, round, max, min, <, >, <=, >= size, concat, substring, toInteger, toReal

Object Constraint Language, May 12, 2008 2

Collections
Collection: an abstract type with four concrete collection types 3 Set: the mathematical set (without duplicate elements) Set {1 , 2 , 5} Set {apple, orange, strawberry} 3 OrderedSet: a set in which the elements are ordered by their position OrderedSet {5, 4, 3, 2, 1} 3 Bag: a set that may contain duplicate elements Bag {1, 2, 5, 2} 3 Sequence: a bag in which the elements are ordered Sequence {1, 2, 5, 10} Sequence {ape, nut} Notation .. used for a sequence of consecutive integers 3 Sequence {1..5} is the same as Sequence {1, 2, 3, 4, 5} Elements of collections may be collections themselves Set { Sequence {1, 2, 3, 4}, Sequence {5, 6} } Collections have a set of predened operations 3 They are accessed using the -> notation 5

Common Operations for All Collections


C, C1 , C2 are values of type Collection(t), v is a value of type t Signature Collection(t) Integer Collection(t) t Integer Collection(t) t Boolean Collection(t) t Boolean Collection(t) Collection(t) Boolean Collection(t) Collection(t) Boolean Collection(t) Boolean Collection(t) Boolean Collection(t) t Semantics |C| | C {v} | vC vC C2 C1 C2 C1 = C= C= |C| i=1 vi

size count includes excludes includesAll excludesAll isEmpty notEmpty sum

Object Constraint Language, May 12, 2008 3

Set Operations
S, S1 , S2 are values of type Set(t), B is a value of type type t Signature union Set(t) Set(t) Set(t) union Set(t) Bag(t) Bag(t) intersection Set(t) Set(t) Set(t) intersection Set(t) Bag(t) Set(t) Set(t) Set(t) Set(t) symmetricDifference Set(t) Set(t) Set(t) including Set(t) t Set(t) excluding Set(t) t Set(t) asSet Set(t) Set(t) asOrderedSet Set(t) OrderedSet(t) asBag Set(t) Bag(t) asSequence Set(t) Sequence(t) Bag(t), v is a value of Semantics S1 S2 SB S1 S2 SB S1 S2 (S1 S2 ) (S2 S1 ) S {v} S {v}

Operations asOrderedSet and asSequence are nondeterministic Result contains the elements of the source set in arbitrary order

Bag Operations
B, B1 , B2 are values of type Bag(t), S is a value of type Set(t), v is a value of type t union union intersection intersection including excluding asSet asOrderedSet asBag asSequence Signature Bag(t) Bag(t) Bag(t) Bag(t) Set(t) Bag(t) Bag(t) Bag(t) Bag(t) Bag(t) Set(t) Set(t) Bag(t) t Bag(t) Bag(t) t Bag(t) Bag(t) Set(t) Bag(t) OrderedSet(t) Bag(t) Bag(t) Bag(t) Sequence(t) Semantics B1 B2 BS B1 B2 BS S {{v}} S {{v}}

Object Constraint Language, May 12, 2008 4

Sequence Operations
S, S1 , S2 are values of type Set(t), v is a value of type t, operator denotes j the concatenation of lists, i (S) projects the ith element of a sequence S, i (S) is the subsequence of S from the ith to the jth element union append prepend subSequence at first last including excluding asSet asOrderedSet asBag asSequence Signature Sequence(t) Sequence(t) Sequence(t) Sequence(t) t Sequence(t) Sequence(t) t Sequence(t) Sequence(t) Integer Integer Sequence(t) Sequence(t) Integer Sequence(t) Sequence(t) t Sequence(t) t Sequence(t) t Sequence(t) Sequence(t) t Sequence(t) Sequence(t) Set(t) Sequence(t) OrderedSet(t) Sequence(t) Bag(t) Sequence(t) Sequence(t) Semantics S1 S2 S v v S j i (S) i (S) 1 (S) |S| (S) S v S {v}

Type Conformance
OCL is a typed language, the basic value types are organized in a type hierarchy The hierarchy determines conformance of the dierent types to each other Type type1 conforms with type type2 when an instance of type1 can be substituted at each place where an instance of type2 is expected Valid expression: OCL expression in which all types conform

10

Object Constraint Language, May 12, 2008 5

Type Conformance Rules


Type1 conforms to Type2 when they are identical Type1 conforms to Type2 when it is a subtype of Type2 Collection(Type1) conforms to Collection(Type2) when Type1 conforms to Type2 Type conformance is transitive: if type1 conforms with type2 and type2 conforms with type3, then type1 conforms with type3 Example: If Bicycle and Car are subtypes of Transport 3 Set(Bicycle) conforms to Set(Transport) 3 Set(Bicycle) conforms to Collection(Bicycle) 3 Set(Bicycle) conforms to Collection(Transport) 3 Set(Bicycle) does not conform to Bag(Bicycle)

11

Class Diagram Example


Bank Job accountNo: Integer 0..* customer 0..1 employee 0..* 1 manager 0..* wife employer 0..* Company title: String startDate: Date salary: Integer enumeration Gender male female

Person firstName: String lastName: String gender: Gender birthDate: Date age: Integer isMarried: Boolean 0..1 maidenName: String [0..1] isUnemployed: Boolean parents income(): Integer currentSpouse(): Person descendants(): Set children 0..*

name:String 0..* /noEmployees: Integer managedCompanies stockPrice(): Real hireEmployee(p: Person) Marriage place: String date: Date ended: Boolean

0..* husband

12

Object Constraint Language, May 12, 2008 6

Comments, Inx Operators


Comments Denoted by --- this is a comment Inx Operators Use of inx operators (e.g., +, -, =, <, . . .) is allowed Expression a + b is conceptually equivalent to a.+(b), i.e., invoking the + operation on a with b as parameter Inx operators dened for a type must have exactly one parameter

13

Context and Self


All classiers (types, classes, interfaces, associations, datatypes, . . .) from an UML model are types in the OCL expressions that are attached to the model Each OCL expression is written in the context of an instance of a specic type context Person ... Reserved word self is used to refer to the contextual instance If the context is Person, self referes to an instance of Person

14

Object Constraint Language, May 12, 2008 7

Object and Properties


All properties (attributes, association ends, methods and operations without side eects) dened on the types of a UML model can be used in OCL expressions The value of a property of an object dened in a class diagram is specied by a dot followed by the name of the property If the context is Person, self.age denotes the value of attribute age on the instance of Person identied by self The type of the expression is the type of attribute age, i.e., Integer If the context is Company, self.stockPrice() denotes the value of operation stockPrice on the instance identied by self Parentheses are mandatory for operations or methods, even if they do not have parameters

15

Invariants
Determine a constraint that must be true for all instances of a type Value of attribute noEmployees in instances of Company must be less than or equal to 50 context Company inv: self.noEmployees <= 50 Equivalent formulation with a c playing the role of self, and a name for the constraint context c: Company inv SME: c.noEmployees <= 50 The stock price of companies is greater than 0 context Company inv: self.stockPrice() > 0

16

Object Constraint Language, May 12, 2008 8

Pre- and Post-conditions


Constraints associated with an operation or other behavioral feature Pre-condition: Constraint assumed to be true before the operation is executed Post-condition: Constraint satised after the operation is executed Pre- and post-conditions associated to operation income in Person context Person::income(): Integer pre: self.age >= 18 post: result < 5000 self is an instance of the type which owns the operation or method result denotes the result of the operation, if any Type of result is the result type of the operation (Integer in the example) A name can be given to the pre- and post-conditions context Person::income(): Integer pre adult: self.age >= 18 post resultOK: result < 5000

17

Previous Values in Postconditions


In a postcondition, the value of a property p is the value upon completion of the operation The value of p at the start of the operation is referred to as p@pre context Person::birthDayHappens() post: age = age@pre + 1 For operations, @pre is postxed to the name, before the parameters context Company::hireEmployee(p: Person) post: employee = employee@pre->including(p) and stockPrice() = stockPrice@pre() + 10 The @pre postx is allowed only in postconditions Accessing properties of previous object values 3 a.b@pre.c: the new value of c of the old value of b of a 3 a.b@pre.c@pre: the old value of c of the old value of b of a

18

Object Constraint Language, May 12, 2008 9

Body Expression
Used to indicate the result of a query operation Income of a person is the sum of the salaries of her jobs context Person::income(): Integer body: self.job.salary->sum() Expression must conform to the result type of the operation Denition may be recursive: The right-hand side of the denition may refer to the operation being dened A method that obtains the direct and indirect descendants of a person context Person::descendants(): Set body: result = self.children->union( self.children->collect(c | c.descendants()) ) Pre-, and postconditions, and body expressions may be mixed together after one operation context context Person::income(): Integer pre: self.age >= 18 body: self.job.salary->sum() post: result < 5000 19

Let Expression
Allows to dene a variable that can be used in a constraint context Person inv: let numberJobs: Integer = self.job->count() in if isUnemployed then numberJobs = 0 else numberJobs > 0 endif A let expression is only known within its specic expression

20

Object Constraint Language, May 12, 2008 10

Denition Expressions
Enable to reuse variables or operations over multiple expressions Must be attached to a classier and may only contain variable and/or operation denitions context Person def: name: String = self.firstName.concat( ).concat(lastName) def: hasTitle(t: String): Boolean = self.job->exists(title = t) Names of the attributes/operations in a def expression must not conict with the names of attributes/association ends/operations of the classier

21

Initial and Derived Values


Used to indicate the initial or derived value of an attribute or association end Attribute isMarried in Person is initialized to false context Person::isMarried: Boolean init: self.isMarried = false Attribute noEmployees in Company is a derived attribute context Company::noEmployees: Integer derive: self.employee->size() For an attribute: expression must conform to the attribute type For an association end: conformance depends on multiplicity 3 at most one: expression must conform to the classier at that end 3 may be more than one: expression must conform to Set or OrderedSet

22

Object Constraint Language, May 12, 2008 11

Enumeration Types
Person gender: Gender isMarried: Boolean maidenName: String [0..1] ... enumeration Gender male female

Dene a number of literals that are the possible values of the enumeration An enumeration value is referred as in Gender::female Only married women can have a maiden name context Person inv: self.maidenName <> implies self.gender = Gender::female and self.isMarried = true

23

Packages
Within UML, types are organized in packages Previous examples supposed that the package in which the classier belongs is clear from the environment The package and endpackage statements can be used to explicitly specify this package Package::SubPackage context X inv: ... some invariant ... context X::operationName(...): ReturnType pre: ... some precondition ... endpackage For referring to types in other packages the following notations may be used Packagename::Typename Packagename1::Packagename2::Typename

24

Object Constraint Language, May 12, 2008 12

Undened Values
One or more subexpressions in an OCL expression may be undened In this case, the complete expression will be undened Exceptions for Boolean operators 3 true or anything is true 3 false and anything is false 3 false implies anything is true 3 anything implies true is true The rst two rules are valid irrespective of the order of the arguments and whether or not the value of the other sub-expression is known Exception for if-then-else expression: it will be valid as long as the chosen branch is valid, irrespective of the value of the other branch

25

Navigating Associations (1)


Person employee 0..* employer 0..* Company

isUnemployed: Boolean 1 ... manager

noEmployees:Integer 0..* ... managedCompanies

From an object, an association is navigated using the opposite role name context Company inv: self.manager.isUnemployed = false inv: self.employee->notEmpty() Value of expression depends on maximal multiplicity of the association end 3 1: value is an object 3 *: value is a Set of objects (an OrderedSet if association is {ordered}) If role name is missing, the name of the type at the association end starting with a lowercase character is used (provided it is not ambiguous) context Person inv: self.bank.balance >= 0

26

Object Constraint Language, May 12, 2008 13

Navigating Associations (2)


When multiplicity is at most one, association can be used as a single object or as a set containing a single object self.manager is an object of type Person context Company inv: self.manager.age > 40 self.manager as a set context Company inv: self.manager->size() = 1 For optional associations, it is useful to check whether there is an object or not when navigating the association context Person inv: self.wife->notEmpty() implies self.gender = Gender::male and self.husband->notEmpty() implies self.gender = Gender::female OCL expressions are read and evaluated from left to right

27

Association Classes
Person isUnemployed: Boolean age: Integer ... employee 0..* Job title: String ... employer 0..* Company noEmployees:Integer ...

For navigating to an association class: a dot and the name of the association class starting with a lowercase character is used context Person inv: self.isUnemployed = false implies self.job->size() >= 1 For navigating from an association class to the related objects: a dot and the role names at the association ends is used context Job inv: self.employer.noEmployees >= 1 inv: self.employee.age >= 18 This always results in exactly one object 28

Object Constraint Language, May 12, 2008 14

Recursive Association Classes (1)


Person gender: Gender 0..* isMarried: Boolean ... wife currentSpouse() : Person 0..* husband Marriage place: String date: Date ended: Boolean

Direction in which a recursive association is navigated is required Specied by enclosing the corresponding role names in square brackets A person is currently married to at most one person context Person inv: self.marriage[wife]->select(m | m.ended = false)->size()=1 and self.marriage[husband]->select(m | m.ended = false)->size()=1 May also be used for non-recursive associations, but it is not necessary context Person inv: self.job[employer] ...

29

Recursive Association Classes (2)


Person gender: Gender 0..* isMarried: Boolean ... wife currentSpouse() : Person 0..* husband Marriage place: String date: Date ended: Boolean

Operation that selects the current spouse of a person context Person::currentSpouse() : Person pre: self.isMarried = true body: if gender = Gender::male self.marriage[wife]->select(m | m.ended = false).wife else self.marriage[husband]->select(m | m.ended = false).husband end

30

Object Constraint Language, May 12, 2008 15

Qualied Associations
Bank customer 0..1 * Person

accountNo: Integer

Qualied associations use one or more qualier attributes to select the objects at the other end of the association A bank can use the accountNumber attribute to select a particular customer Using qualier values when navigating through qualied associations context Bank inv: self.customer[12345] ... -- results in one Person, having account number 12345 Leaving out the qualier values context Bank inv: self.customer ... -- results in a Set(Person) with all customers of the bank

31

Re-typing or Casting
Allows an object to be re-typed as another type Expression o.oclAsType(Type2) re-types an object o of type Type1 into a another type Type2 Suppose Super is a supertype of type Sub Allows one to use a property of an object dened on a subtype of the currently known type of the object context Super inv: self.oclAsType(Sub).p -- accesses the p property defined in Sub Can be used to access a property of a superclass that has been overriden context Sub inv: self.p -- accesses the p property defined in Sub self.oclAsType(Super).p -- accesses the p property defined in Super

32

Object Constraint Language, May 12, 2008 16

Predened Properties on All Objects


Several properties apply to all objects 3 oclIsTypeOf(t: Type): Boolean is true if the type of self and t are the same 3 oclIsKindOf(t: Type): Boolean is true if t is a direct/indirect type of self 3 oclInState(s: State): Boolean is true if self is in the state s 3 oclIsNew: Boolean, in a postcondition, is true if self has been created while performing the operation Example context Person inv: self.oclIsTypeOf(Person) -- is true inv: self.oclIsTypeOf(Company) -- is false

33

Class Features
Features of a class, not of its instances They are either used-dened or predened Predened feature allInstances holds on all types There are at most 100 persons context Person inv: Person.allInstances()->size() <= 100 A user-dened feature averageAge of class Person context Person inv: Person.averageAge = Person.allInstances()->collect(age)->sum()/ Person.allInstances()->size()

34

Object Constraint Language, May 12, 2008 17

Select Operation on a Collection


Obtains the subset of elements of a collection satisfying a Boolean expression Alternative expressions for the select operation 3 collection->select(Boolean-expression) 3 collection->select(v | Boolean-expression-with-v) 3 collection->select(v: Type | Boolean-expression-with-v) A company has at least one employee older than 50 context Company inv: self.employee->select(age > 50)->notEmpty() context Company inv: self.employee->select(p | p.age > 50)->notEmpty() context Company inv: self.employee->select(p: Person | p.age > 50)->notEmpty()

35

Reject Operation on a Collection


Obtains the subset of all elements of the collection for which a Boolean expression evalutes to False Alternative expressions for the reject operation 3 collection->reject(Boolean-expression) 3 collection->reject(v | Boolean-expression-with-v) 3 collection->reject(v: Type | Boolean-expression-with-v) The collection of employees of a company who have not at least 18 years old is empty context Company inv: self.employee->reject(age>=18)->isEmpty() A reject expression can always be restated as a select with the negated expression

36

Object Constraint Language, May 12, 2008 18

Collect Operation on a Collection


Derives a collection from another collection, but which contains dierent objects from the original collection Alternative expressions for the collect operation 3 collection->collect(expression) 3 collection->collect(v | expression-with-v) 3 collection->collect(v: Type | expression-with-v) Collect of birth dates for all employees in the context of a Company object 3 self.employee->collect(birthDate) 3 self.employee->collect(p | p.birthDate) 3 self.employee->collect(p:Person | p.birthDate) Resulting collection above is a Bag: some employees may have the same birth date

37

ForAll Operation on a Collection


Species a Boolean expression that must be true for all elements in a collection Alternative expressions for the forall operation 3 collection->forAll(Boolean-expression) 3 collection->forAll(v | Boolean-expression-with-v) 3 collection->forAll(v: Type | Boolean-expression-with-v) The age of each employee is less than or equal to 65 context Company inv: self.employee->forAll(age <= 65) inv: self.employee->forAll(p | p.age <= 65) inv: self.employee->forAll(p: Person | p.age <= 65) More than one iterator can be used in the forAll operation All instances of persons have unique names context Person inv: Person.allInstances()->forAll(p1, p2 | p1 <> p2 implies p1.name <> p2.name )

38

Object Constraint Language, May 12, 2008 19

Exists Operation on a Collection


Species a Boolean expression that must be true for at least one element in a collection Alternative expressions for the exists operation 3 collection->exists(Boolean-expression) 3 collection->exists(v | Boolean-expression-with-v) 3 collection->exists(v: Type | Boolean-expression-with-v) The firstName of at least one employee is equal to Jack context Company inv: self.employee->exists(firstName = Jack) inv: self.employee->exists(p | p.firstName = Jack) inv: self.employee->exists(p: Person | p.firstName = Jack)

39

Iterate Operation on a Collection


Provides a generic mechanism to iterate over a collection Syntax collection->iterate(elem: Type; acc: Type = <expression> | expression-with-elem-and-acc) 3 elem: the iterator as in select, forAll, etc. 3 acc: the accumulator with an initial value <expression> 3 expression-with-elem-and-acc: is evaluated for each elem and its value is assigned to acc The operations select, reject, forAll, exists, collect, can all be described in terms of iterate For example, collection->collect(x: T | x.property) is identical to collection->iterate(x: T; acc: T2 = Bag{} | acc->including(x.property))

40

Object Constraint Language, May 12, 2008 20

Company Example: Class Diagram


Manages Employee SSN firstName lastName birthDate sex salary address hireDate supervisor 0..1 age() 0..* subordinates Supervision 1 0..* dependents Dependent name relationship sex birthDate 1 4..* 1..* WorksFor startDate 0..1 1 Department number name locations [1..*] /nbrEmployees 1..* WorksOn 1..* hours Controls 1 Project number name location

41

Company Example: Integrity Constraints (1)


The age of employees must be greater than or equal to 18 context Employee inv: self.age() >= 18 The supervisor of an employee must be older than the employee context Employee inv: self.supervisor->notEmpty() implies self.age() > self.supervisor.age() The condition notEmpty must be tested since the multiplicity of the role is not mandatory The salary of an employee cannot be greater than the salary of his/her supervisor context Employee inv: self.supervisor->notEmpty() implies self.salary < self.supervisor.salary The hire date of employees must be greater than their birth date context Employee inv: self.hireDate > self.birthDate

42

Object Constraint Language, May 12, 2008 21

Company Example: Integrity Constraints (2)


The start date of an employe as manager of a department must be greater than his/her hire date context Employee inv: self.manages->notEmpty() implies self.manages.startDate > self.hireDate A supervisor must be hired before every employee s/he supervises context Employee inv: self.subordinates->notEmpty() implies self.subordinates->forall( e | e.hireDate > self.hireDate ) The manager of a department must be an employee of the department context Department inv: self.worksFor->includes(self.manages.employee) The SSN of employees is an identier (or a key) context Employee inv: Employee.allInstances->forAll( e1, e2 | e1 <> e2 implies e1.SSN <> e2.SSN )

43

Company Example: Integrity Constraints (3)


The name and relationship of dependents is a partial identier: they are unique among all dependents of an employee context Employee inv: self.dependents->notEmpty() implies self.dependents->forAll( e1, e2 | e1 <> e2 implies ( e1.name <> e2.name or e1.relationship <> e2.relationship )) The location of a project must be one of the locations of its department context Project inv: self.controls.locations->includes(self.location) The attribute nbrEmployees in Department keeps the number of employees that works for the department context Department inv: self.nbrEmployees = self.worksFor->size() An employee works at most in 4 projects context Employee inv: self.worksOn->size() <= 4

44

Object Constraint Language, May 12, 2008 22

Company Example: Integrity Constraints (4)


An employee may only work on projects controlled by the department in which s/he works context Employee inv: self.worksFor.controls->includesAll(self.worksOn.project) An employee works at least 30h/week and at most 50 h/week on all its projects context Employee inv: let totHours: Integer = self.worksOn->collect(hours)->sum() in totHours >= 30 and totHours <=50 A project can have at most 2 employees working on the project less than 10 hours context Project inv: self.worksOn->select( hours < 10 )->size() <= 2

45

Company Example: Integrity Constraints (5)


Only department managers can work less than 5 hours on a project context Employee inv: self.worksOn->select( hours < 5 )->notEmpty() implies Department.allInstances()->collect(manages.employee)-> includes(self) If the manager of a department must be an employee of the department (previous contraint), this constraint can be specied as follows context Employee inv: self.worksOn->select( hours < 5 )->notEmpty() implies self.worksFor.manages.employee=self Employees without subordinates must work at least 10 hours on every project they work context Employee inv: self.subordinates->isEmpty() implies self.worksOn->forAll( hours >=10 )

46

Object Constraint Language, May 12, 2008 23

Company Example: Integrity Constraints (6)


The manager of a department must work at least 5 hours on all projects controlled by the department context Department inv: self.controls->forall( p:Project | self.manages. employee.worksOn->select(hours >= 5)->contains(p) ) An employee cannot supervise him/herself context Employee inv: self.subordinates->excludes(self) The supervision relationship must not be cyclic context Employee def: allSubordinates = self.subordinates->union( self->subordinates->collect(e:Employee | e.allSubordinates)) inv: self.allSubordinates->exludes(self)

47

Object Constraint Language, May 12, 2008 24

Вам также может понравиться