150 likes | 309 Views
Survol de Object Constraint Language & IDM. À partir du cours Contracts, Patterns and Aspects within MDA De Jean-Marc Jézéquel. Un métamodèle. Conformité entre modèles et métamodele. Un métamodele en UML contraint la structure d’un modèle : typage des éléments
E N D
Survol de Object Constraint Language& IDM À partir du cours Contracts, Patterns and Aspects within MDA De Jean-Marc Jézéquel
Conformité entre modèles et métamodele • Un métamodele en UML contraint la structure d’un modèle : • typage des éléments • Cardinalité des associations • Ça ne suffit pas!
Un métamodèle : des contraintes -- (C1) Error: the name of a Classifier must be unique within its package. context Classifier inv: not self.package.contents->exists(e | (e <> self) and (e.name = self.name))
Un métamodèle : des contraintes supplémentaires -- (C2) Error: the name of a StructuralFeature must be unique within its Class --and its supertypes. context StructuralFeature inv: not self.owner.allStructuralFeatures()-> exists(e |(e <> self) and (e.name = self.name))
Invariants de classe en UML Bank_Account {balance>=lowest} balance: Money lowest: Money deposit (Money) withdraw(Money) • Contraintes ajoutées à un modèle UML • notation: between { } • Invariant = expression booléenne • Vraie pour toutes les instances d’une classe dans un état stable … • Exprimée en OCL (Object Constraint Language) • e.g. {balance >= lowest} • Navigation au travers des associations
Precondition:De la responsabilité du client • Spécification de ce qui doit être vraie pour être autorisé à appeler une méthode • example: amount > 0 • Notation en UML • {«precondition» OCL boolean expression} • Abbreviation: {pre: OCL boolean expression}
Postcondition:De la responsabilité de l’implementeur • Specification de ce qui doit être vraie à la fin de l’exécution réussie d’une méthode • example: balance = balance @pre + amount • Notation en UML • {«postcondition» OCL boolean expression} • Abbreviation: {post: OCL boolean expression} • “Operator for previous value (idem old Eiffel):” • OCL expression @pre
To be Abstract and Precise with the UML Bank_Account {balance>=lowest} balance: Money lowest: Money deposit (amount: Money) {pre: amount> 0} {post: balance = balance @pre + amount} withdraw(amount: Money) {pre: amount> 0 and montant<=balance-lowest} {post: balance = balance @pre - amount}
Non-local contracts: navigating associations ownership ownings * 1 owner Person Car • Each association is a navigation path • The context of an OCL expression is the starting point • Rolenames are used to select which association is to be traversed (or target classname if only one) Context Car inv: self.owner.age >= 18
Navigation of 0..* associations • Through navigation, we no longer get a scalar but a collection of objects • OCL defines 3 sub-types of collection • Set : when navigation of a 0..* association • Context Person inv: ownings return a Set[Car] • Each element is in the Set at most once • Bag : if more than one navigation step • An element can be present more than once in the Bag • Sequence : navigation of an association {ordered} • It is an ordered Bag • Many predefined operations on type collection Syntaxe : Collection->operation
Basic operations on collections Context Person inv: age<18 implies ownings->isEmpty • isEmpty • true if collection has no element • notEmpty • true if collection has at least one element • size • Number of elements in the collection • count (elem) • Number of occurrences of element elem in the collection
select Operation • possible syntax • collection->select(elem:T | expr) • collection->select(elem | expr) • collection->select(expr) • Selects the subset of collection for which property expr holds • e.g. • shortcut: context Person inv:ownings->select(v: Car | v.mileage<100000)->notEmpty context Person inv:ownings->select(mileage<100000)->notEmpty
forAll Operation • possibles syntax • collection->forall(elem:T | expr) • collection->forall(elem | expr) • collection->forall(expr) • True iff expr holds for each element of the collection • e.g. • shortcut: context Person inv:ownings->forall(v: Car | v.mileage<100000) context Person inv:ownings->forall(mileage<100000)
forAll with two variables • Considers each pair in the Cartesian product of employees context Company inv: self.employee->forAll( e1, e2 : Person | e1 <> e2 implies e1.forename <> e2.forename) This is the same as self.employee->forAll(e1 | self.employee-> forAll (e2 | e1 <> e2 implies e1.forename <> e2.forename)))