Upload
karen-sims
View
231
Download
1
Embed Size (px)
Citation preview
ניתוח ועיצוב מערכות תוכנה
2012אביב העצמים אילוצי שפת
Object Constraints Language(OCL)
1
OutlineWhat is OCLTypes of constraintsConstraints structureOCL expressions Examples
Textbook: Jos Warmer and Anneke Kleppe,“The Object Constraint Language”Available on Google Books
2
What is OCL It is intended for the specification of
additional requirements (constrains) which cannot or be expressed graphically. To specify invariants on classes and types in the
class model. To describe pre- and post- conditions on
operations. To describe guards. To specify target (sets) for messages and actions. To specify constraints on operations. To specify derivation rules for attributes for any
expression over a UML model.
3
Types of Constraints An invariant is a constraint that states a condition that
must always be met by all instances of the class, type, or interface.An invariant is described using an expression that
evaluates to true if the invariant is met. Invariants must be true all the time (Class diagram).
A precondition to an operation is a restriction that must be true at the moment that the operation is going to be executed.The obligations are specified by post conditions
(Sequential diagram). A postcondition to an operation is a restriction that must be
true at the moment that the operation has just ended its execution (Sequential diagram).
A guard is a constraint that must be true before a state transition fires (State machine diagram).
4
Constraints Structurecontext Typename c_type [name]: <OCL–expression>
The context is keyword introduces the context for the expression. Each OCL expression is written in the context of an instance of a specific type.
Typename is the name of the type or the class for which the invariant constrain applies.
c_type is the type of the constrain: invariant, pre/post-condition, guard.
[name] – optional, the names of the constraint. OCL - expression should accept value “true” for all instances of
Typename.
For example:Context Packagename1::class1 inv : …Context class2 inv : …
5
Basic Data Types
Type OperationsBoolean and, or, xor, not, if-then-else, …Integer multiply, add, subtract, divide, compare…Real multiply, add, subtract, divide, compare…String toUpper, toLower, concat, …
6
Operations above basic types of data (Boolean, Integer, Real, String);
Collectionsset : the mathematical set.
It is not ordered and does not contain duplicate elements.
bag : A container. It is not ordered and contain duplicate elements.
sequence : An container. It is ordered and contain duplicate elements.
collection asSet() : can be used to convert any collection into a set (remove duplicates).
7
Implies:
Operations on collections.
Do not mix ‘’ with ‘implies’ as in logical notation!
implies operator, operator
A=T,B=T
A=T,B=F
A=F,B=T
A=F,B=F
A implies B T F T T
8
Collection Operations• <collection> → …
→ isEmpty( )
→ notEmpty ( )
→ exists ( e:T | <b.e.>) isUnique(e:T | <v.e>)
Boolean: → forAll ( e:T* | <b.e.>) forAll(e:T1,f;T2|<b.e.>)
→ excludes ( object )
→ includes ( object )
→ includesAll ( collection )
→ count ( object )
Numeral: → size ( )
→ sum ( )
→ select ( e:T | <b.e.>) asSet()
Collections: → reject ( e:T | <b.e.>) including(object), excluding(object)
→ collect ( e:T | <v.e.>) includingAll(collection), excludingAll(collection)
Generic: → iterate ( e:T1; r:T2 = <v.e.> | <v.e.>)
• b.e. stands for: boolean expression
• v.e. stands for: value expression
(as seen in the Structural Modeling, Part B lecture (slides 59-60)). 9
Collection Operations - Selectselect ( e:T | <b.e.>): SQL-like select, returning a sub-collection of the original.
animals select(a:Animal | a.family == “Reptile”)
reject ( e:T | <b.e.>) is select’s complementary operation.
From a collection of animals – to a <= collection of animals!
e stands for iterator expression, T stands for type. b.e. stands for: boolean expression v.e. stands for: value expression
10
Collection Operations - Collectcollect ( e:T | <v.e.>): from every member of the collection, take something. Thus this operation might return a collection of different type than the original!
animals collect(a:Animal | a.name)
From a collection of animals– to a collection of strings!
Shorthand Notation: students.studentCard – only in ‘collect’!!!
11
Alice Bob Carol Dave
Eve Mallory Peggy Victor
Trent Trudy Walter Paul
OCL – expression Operations above objects:
<class>.<attribute><class>.<role>.<attribute>
(preferred)<class>.<class name>.<attribute>
1. context Employee inv: self.age>17 and self.age<=100
2. context Employee inv: self.age>30 or self.workplace.number<5
3. context Department inv:self.number<5 or self.employee select(age<=30)size()=0
3. context Department inv:self.employeeexist(job=“manager”) and self.company.year<=self.year
4. context Company inv:self.department.employee forAll(age<=67)
Operations above collections:<collection> → <operation>
:דוגמאות
ל- 18גיל העובדים חייב להיות בין 1.100
5גיל מינימלי של העובדים במחלקות 2..31ומעלה חייב להיות לפחות
לכל מחלקה חייב להיות "מנהל" ושנת 3.הקמת המחלקה לא מוקדם משנת הקמת
החברהפנסיונרים לא מועסקים בחברה4.12
Example 1: treating collections as instances, enumerations
If a person has a wife, she must be female and the person must be male. ⇒ context Person inv: WifenotEmpty() implies(wife.gender=Gender::female and self.gender=Gender::male)//note: after a collection has been validated to be of size 1, it can be treated as an instance!
If a person has a husband, he must be male and the person must be female. ⇒ context Person inv: HusbandnotEmpty() implies(husband.gender=Gender::male and self.gender=Gender::female)
13
)אם האדם מובטל אז()יוצר אוסף של ערכי הרכבים שברשותו(
(500000)חשב סכום ערכי הרכבים תבדוק שהוא קטן מ-
)יוצר אוסף של צבעי הרכבים שברשותו(
- השאר אחד מכל צבע(set)הפוך את האוסף ל
צבעים(3)ספירת כמות צבעים ובדיקה שאין יותר מ
Example 1 (Cont.)
If a person is male he can't have pink car⇒ context Person inv: (self.gender==Gender::male) implies(self.ownsselect(c|c.color==‘pink’)size()=0)
If a person is unemployed he can't own cars in value of more then 500,000$⇒ context Person inv: (self.unemployed) implies
(self.owns collect(c | c.value) sum()<= 500000)
A person can’t have cars in more then 3 different colors⇒ context Person inv: self.owns collect(c|c.color)
asSet() size()<=3
14
Example 1 (Cont.)
A person between the age of 0 to 18 can’t own a yellow car while person between the age of 18 and 21 can own one yellow car at most and a person older then 21 can own as many yellow cars as he like.⇒ context Person inv:let amountOfYellowCars : Integer =
self.ownsselect(c:Car | c.color = “yellow”)size()in
if (self.age < 18) then(amountOfYellowCars = 0) else if (self.age < 21) then (amountOfYellowCars <= 1)
else true endif
endif
15
Example 2
The sum of the values of all securities must be at least 20% more than the amount of the credit. ⇒ context Credit inv sufficientSecurities:
securities.Value sum()> self.Amount * 1.2
A credit of a given customer can only be secured by securities that are owned by the given customer. ( הלוואה של לקוח נתון מאובטחת רק ע"י⇒ ( ערבויות ששייכות לאותו הלקוח context Credit inv onlyOwnedSecurities:
securities.ownerforAll(aa:Customer|aa = self.customer) aa is instance of owner!!!!
16
Instance and Type OperationsInstances have the following operations:self.oclIsTypeOf(T)
returns true iff self is of type Tself.oclIsKindOf(T)
returns true iff (self is of type T) V (self’s subtype of T)Self.oclAsType(T)
used for casting (for instance, from Abstract class to Subclass).Types have the ‘allInstances’ member:T.allInstances
returns a collection of all T instances.Example: “At least 1 animal has to eat meat”:Animals.allInstances exists(a:Animal|a.eats == “Meat”)In reality, this is usually frowned upon (we’ll see it later!)
17
Example 3: allInstances, type checks, recursion
All people should be married⇒ context Person inv:Person.allInstancesforAll(p:Person | p.married)
In a Class all the Attributes have different names.⇒ context Class inv: self.features
select(f|f.oclIsTypeOf(Attribute))isUnique(a:Attribute|a.name)
18
)collection of Features(
)collection of Attributes(
Association Class
Navigate to an association class:If the context is Teacher, you could navigate to the association
class with the expression: self.Room. This expression would result in a collection of all the room
assignments for all the courses to which the teacher is assigned.
Navigate from an association class to either end of the association:Starting with a context of the Room class, the expressions:
self.instructor self.course is valid. Navigating from an association class always results in a single
object.19
*
Example 4 - Train
All trains must own at least one wagon⇒ context Train inv atLeastOneWagon:self.wagon size() >= 1
A wagon and its successor wagon should belong to the same train⇒ context Wagon inv belongToTheSameTrain:self.succ notEmpty() implies self.succ.train = self.train
All the trains will have the same number of wagons⇒ context Train inv sameNumberOfWagons:Train.allInstances forAll(x:Train,y:Train | x.wagonsize() = y.wagonsize() )
20
Example 4 - Train
There do not exists two different wagons directly linked to each other in a cyclic way⇒ not necessary : consider two wagon instances w1,w2.⇒ If these two instances are linked with an ‘Order’ link, one has to assume the role of ‘succ’ and the second must assume the role of ‘pred’ – two can’t close a cycle!
But how do you prevent a cycle of > 2 wagons?
Context Train inv NoCycles:Wagoncollect(w | w.succ)size() = Wagon.size()-1
Will this work?
21
22
Advanced Topics in OCLTypes and Subtypes via oclIsTypeOf and oclIsKindOf
23
Advanced Topics in OCL
24
Advanced Topics in OCL
Preconditions, Postconditions, Operations (sic, p.155)
Navigation into class method using ‘::’post : result = participants This is how we define the
result!Keywords: <attribute>@pre , pre , post , result .
25
Advanced Topics in OCL
Avoid allInstances (Warmer and Kleppe, p.67)“A Person has no more than 2 parents:”context PersonInv: parents size() <= 2context PersonInv: Person.allInstancesforAll(p:Person|p.parentssize()<= 2)“The use of allInstances is discouraged, because it makes the
invariant more complex [even to the point of hiding it.]...“In most systems... It is difficult to find all instances of a class.
Unless an explicit tracking device keeps a record of all instances of a certain class as they are created and deleted, there is no way to find them. Thus, there is no way to implement the invariant using a programming language equivalent to the allInstances operation.
26
Advanced Topics in OCL
And this is just the beginning...
Handling message-passing between objectsTuples and Tuple TypesUnvefined Values: the OclVoid typeRetyping or Casting
Unfortunately, these along with many otherOCL features are out of the scope ofour course.
27
Advanced Topics in OCL