Sei sulla pagina 1di 38

ECE 649 Fall 2007

Advanced
Software Engineering
Object Constraint Language

Ramtin Khosravi

OCL Topics
z

Object Constraint Language (OCL)

OCL for Design by Contract

OCL for Queries

Another OCL Example

OCL Topics
z

Object Constraint Language (OCL)

OCL for Design by Contract

OCL for Queries

Another OCL Example

Object Constraint Language


z
z

OCL 2.0
Product of the Object Management Group
(OMG)

Add-on to the Unified Modeling Language


(UML) 2.0 specification

UML combined with OCL forms a solid base for


Model Driven Architecture (MDA)

Model Driven Architecture


z

Work with Platform


Independent Model
(PIM)

Transform PIM into


Platform Specific
Model (PSM)

Transform PSM into


implementation

Model Constraints
z

Originally viewed as a way to constrain or


to restrict values in a model

In addition OCL supports:


Query expressions
Derived values
Conditions
Business rules

z
z
z
z

Reasons to use OCL


z

Express concepts that are not supported


by UML diagrams

Make models more precise

Support transformation tools and code


generation (MDA)

OCL Topics
z

Object Constraint Language (OCL)

OCL for Design by Contract

OCL for Queries

Another OCL Example

Design by Contract
z
z

Why do we use contracts?


We know the rules. We know what
happens if we break them.

Design by Contract does the same for


software.

Provide a formal specification of behavior.

More Design by Contract


z

winningBid():Bid is a signature, not a


specification. Its like giving someone a
phone without providing the format for a
correct phone number.

Are there any conditions that must be met


for a call to winningBid() to succeed?

And Design by Contract


z

Specify preconditions, postconditions, and


invariants. Defensive programming?

Well cover each of these in turn.

Bertrand Meyer is the father of DbC


http://www2.inf.ethz.ch/personal/meyer/

Auction Domain

A partial auction domain to get us started.


Includes Auction, Bid, and Money.

We have the structure, but what are the rules?

Auction Domain

OCL Expression Context

Every OCL expression takes place in a context:

context Auction
context Auction::winningBid():Bid

Preconditions

Preconditions are the conditions that must be


true prior to successfully invoking the method in
question.
Often preconditions that fail result in exceptions.

Example Preconditions
z
z
z
z
z
z

context Auction::placeBid(bidder:Id,
bid:Money)
pre : not bidder.oclIsUndefined()
pre : not bid.oclIsUndefined()
pre : bid.currency =
self.bids->first().amount.currency
pre : bid > self.currentBid().money

Simple Preconditions
z

z
z

context Auction::placeBid(bidder:Id,
bid:Money)
pre : not bidder.oclIsUndefined()
pre : not bid.oclIsUndefined()

This operation requires a bidder identifier and


a bid.

Implementing Preconditions
z
z
z
z
z
z
z
z

public void placeBid(Id bidder,


Money bid) {
if (bidder == null) {
throw new NullPointerException(
bidder may not be null);
}

More Involved Preconditions


z
z
z
z

context Auction::placeBid(bidder:Id,
bid:Money)
pre : bid.currency =
self.bids->first().amount.currency
pre : bid > self.currentBid().money
The bid must be in the same currency as the
starting bid. The bid must be higher than the
current high bid.

Implementing Preconditions
z
z
z
z
z
z
z
z

if (bid.getAmount().getCurrency() !=
((Bid) bids.first()).getAmount()
.getCurrency()) {
throw new IllegalArgumentException(
currencies must match);
}

10

Assertion Temptation
z
z
z
z
z
z
z
z
z
z

// Dont do this. Anyone who runs your app


// can turn off assertions.

assert bidder != null :


bidder may not be null;
assert bid.getAmount().getCurrency() ==
((Bid) bids.first()).getAmount()
.getCurrency() :
currencies must match;

OCL Comments

context Auction::placeBid(bidder:Id,
bid:Money)
-- currencies must match
pre : bid.currency =
self.bids->first().amount.currency
pre alwaysTrue : 1 = 1

-- and /**/ are valid comment forms in OCL

z
z
z
z

11

More Preconditions

Preconditions are not limited to checking


parameters. They can specify any condition that
must be true prior to executing the operation.
What are some other possible preconditions?

More Preconditions
z
z
z

z
z
z

context Auction::winningBid():Bid
-- auction must end to have a winner
pre : TimeStamp::now() >=
self.expires()
context Bid::>(bid:Bid):Boolean
-- _gt is our name for >
pre : not bid.oclIsUndefined()

12

Invariants

Invariants are conditions that are always true.

They are always true. Think conservation of


energy, not the color of the sky is blue.

Invariants

If an invariant is violated something is wrong


with the implementation of your system.

What are some invariants in our domain?

13

Example Invariants
z
z

z
z
z
z

context Auction
inv : self.expires() > self.start
context Bid
inv : self.amount.amount > 0.0
/* Note this could be specified in
the Auction context, but dont. */

Postconditions

Postconditions are the conditions that your


operation guarantees will be true when it has
completed.
The contract: You meet the preconditions and Ill
meet the postconditions.

14

PostConditions
z

context Auction::placeBid(bidder:Id,
bid:Money)
post: self.currentBid().amount = bid
Notice that the postcondition assumes serial or
single-threaded execution. This postcondition
isnt necessarily enforceable in an unprotected
multi-threaded context.

PostConditions
z

z
z

z
z
z

context Auction::placeBid(bidder:Id,
bid:Money)
post : self.currentBid() >
self.currentBid@pre()
Postconditions can reach back in time.
@pre references the value before the operation.
Another way to state a precondition

15

Implementing
PostConditions
z
z
z
z
z
z
z

public void placeBid(Id bidder,


Money bid) {

Bid preCurrentBid = this.currentBid();

if (this.currentBid() <= preCurrentBid)


{

OCL Contracts

z
z
z
z

Add more formal specifications to your models.


Specify what will happen, without the how.
Start at component boundaries.
You can start out with simple contracts.

16

OCL Topics
z

Object Constraint Language (OCL)

OCL for Design by Contract

OCL for Queries

Another OCL Example

OCL as Query Language


z

You can think of OCL as equivalent to


SQL when it comes to querying object
models.

Borlands ECO framework uses OCL for


querying (as well as constraints, derived
values, etc.)

z
z

Other query alternatives include


OQL and Xquery

17

Test Results Mini Domain


z

Below is a simple domain for describing test


results from test sessions at a competition for
teams of logicians.
This is our domain for examining OCL queries.

Test Results Mini Domain

18

Example Test Data Set


z

Heres some example test result data from a


logician competition.

Derived Values
z
z

context TestResult::compositeScore : Integer


derive: (2 * logicScore) +
illogicScore

19

OCL Collection Operations


z
z

context TestSession::numberOfResults : Integer


derive: results->size()

OCL Collection Choices


z

z
z

Set: no duplicates, not ordered,


result of navigating on association
OrderedSet: not sorted, just ordered
Bag: may contain duplicates, not ordered,
usually the result of navigating multiple
associations
Sequence: an ordered Bag

20

OCL Collections
Classification

Duplicates

Not Ordered

Ordered

No
Duplicates

Bag

Set

Sequence

OrderedSet

OCL select() Query


z

context TestSession::numberOfScoresOverTarget(
target : Integer) : Integer
body: results->select(compositeScore > target)->size()

21

Translating OCL Queries


z

Lets look at what a transformation tool might do


with one of our queries in SQL.

SELECT COUNT(*) FROM test_results


WHERE composite_score > :target;

team

logic_score

illogic_score

composite_score

name

Blue

24

47

95

A Appell

Blue

24

32

80

B Barry

Red

35

23

93

C Cross

Green

18

50

86

D Dolly

Red

49

44

143

E Elms

Blue

37

42

116

F Fisher

Returning a Collection
z

context TestSession::testResultsForTeam(
testTeam : Team) : Set(TestResult)
body: results->select(team = testTeam)

22

Building Up Queries
z

context TestSession::averageScoreForTeam(
testTeam : Team) : Real
body: testResultsForTeam(testTeam).compositeScore
->sum() / testResultsForTeam(testTeam)->size()

Which Logicians Won?


z
z

context TestSession::bestResults() : Set(TestResult)


body: results->select(compositeScore =
results->sortedBy(compositeScore)
->last().compositeScore)

23

OCL Basic Types


z

Boolean
|

Integer
|

theoretically unlimited natural numbers, subtype


of Real

Real
|

true or false

mathematical Real, no specific implementation


implied

String
|

sequence of characters

Boolean Operations
z

a : Boolean, b : Boolean

a and b
not a
a implies b

z
z

a or b
a=b

a xor b
a <> b

24

Numeric Operators
z
z
z
z

z
z
z

Comparison
=
equals
<
less
<= less or equal

<>
>
>=

not equals
more
more or equal

Math
+ addition
* multiplication

subtraction
division

Every Type in OCL


is an Object
z

a : Integer

b:Integer

a.div(b)
a.max(b)
a.round()

a.mod(b)
a.abs()
a.min(b)
a.floor()

Operators are just infix notation operations.

z
z

25

String Operations
z

a : String

b : String

a <> b
a.size()
a.toUpper()

a=b
a.concat(b)
a.toLower()
a.subString(1, 3)

Operations return new Strings.

z
z

OCL Conditional
z

OCL provides one conditional construct:

if <Boolean expression>
then <expression>
else <expression>
endif

z
z
z

26

OCL Operation Precedence


z
z
z
z
z
z
z
z
z

Grouping
Path resolution
Message notation
Unary
Multiplication/Division
Addition/Subtraction
Comparison
Logical
Logical implication

()
::
. -> also ^ ^^
- not
* /
+ < > <= >= <> =
and or xor
implies

User-Defined Types
z

Classes, Interfaces, etc. defined in the


model

Users may overload infix and unary


operators:
| Multiply

Money by a Real
| Add two Distance values

27

OCL Collections
z
z
z
z

Refreshing our memories, we have:


Collection
Bag
Sequence
Set
OrderedSet
OCL allows you to treat any instance like
a collection. You can ask if a single
attributed is empty.

Collections must by Typed

Set(Bid)
Bag(String)

Like generics in Java or templates in C++.

28

Collections Literals
z

Use curly brackets around comma lists to


specify Collection literals.

Bag {sock, sock, shirt, sweater, sock}


Sequence {abe, bob, bob, tim, zak}
Set {16.0, 2.0, 64.0, 8.0, 128.0, 3.5}
OrderedSet {1, 2, 4, 8, 16, 32, 64, 128}

You can also specify Collections of Collections.

z
z

Basic Collections Operations


z

a : Set(String)

a=c

a <> c

a->size()

a->count(b)

a->excludes(b)
a->excludesAll(c)
a->includes(b)
a->includesAll(c)
a->isEmpty()
a->notEmpty()
a->sum() -- contents are of type supporting +

z
z
z

b : String

c : Set(String)

29

More Collections Operations


z

OCL supports a wide range of Collection


operations that vary by Collection type.

first(), last(), at(i : Integer), etc. for


{ordered} collections

union(), -, asSet(), including(),


symmetricDifference(collection :
Collection) are a sample

Flatten
z

Recursively adds the members of


nested collections to a single
collection.

z
z

context MyType
def: a : Set(Set(Integer)) =
Set {Set{1, 2, 3}, Set{3, 4, 5}, Set{4, 5, 6}}

a->flatten() = Set{2, 3, 1, 5, 4, 6} -- no order

30

Collection Loops
z

z
z

z
z

OCL supports an iterate() operation for


Collections. On top of that idea, OCL
provides a set of Collection operations
that accept expression.
Examples:
any(expression)
exists(expression)
collect(expression)one(expression)
select(expression) reject(expression)

Other OCL Types


z
z
z
z

z
z

OclAny the root Type


OclVoid the null Type undefined
OclType a type, like Class in Java
OCL provides operations for type
identification.
Tuple
Tuple
|

group of named values

{name : String = Dan, role : Role =


Role::Speaker}

31

Liquid Lemons Domain

LL Invariants
z
z
z

z
z

context Sale
-- a Sale has zero or more items
inv numberOfSaleItems :
not items->size() >= 0
-- a Sale's subtotal may not be less than zero
inv subtotalGreaterThanZero : subtotal().amount > 0.0
and subtotal().currency = Currency::USDollars

32

LL Pre and Post


z

z
z
z
z

context LiquidLemons::addLemonade(flavor : Flavor,


size : DrinkSize)
pre activeSale : currentSale->size() = 1
pre mustHaveFlavor : not flavor.oclIsUndefined()
pre mustSpecifySize : not size.oclIsUndefined()
post newLemonade :
currentLemonade->size() = 1

LL Query

33

Collections Queries
z
z

z
z

context ItemAnalyzer::averagePrice() : Money


body: items.basePrice()->sum() / items.basePrice()>size()
context ItemAnalyzer::uniqueModDescriptions() :
Set(String)
body: items.modDescriptions()
->flatten()->asSet()

Composite Queries
z

Use small methods with single responsibilities to


build up larger functions.

-- the total we want is subtotal plus tax


context Sale::total() : Money
body: subtotal() + tax()

z
z

z
z
z

-- tax is the subtotal times the local tax rate


context Sale::tax() : Money
body: subtotal() * Tax::localRate

34

Composite Queries Cont.


z
z

z
z

z
z

context Sale::subtotal() : Money


body: items.price()->sum()
context LineItem::price() : Money
body: basePrice() + modsPrice()
context LineItem::modsPrice() : Money
body: modifiers.price()->sum()

Dont Do This
z
z
z
z
z
z
z
z
z
z
z
z
z
z
z

context LineItem::basePrice() : Money


body:
if size = DrinkSize::Small then
if flavor = Flavor::Regular then
Money::newInstance(1.23, Currency::USDollars)
else
Money::newInstance(1.73, Currency::USDollars)
endif
else
if flavor = Flavor::Regular then
Money::newInstance(2.43, Currency::USDollars)
else
Money::newInstance(3.13, Currency::USDollars)
endif
endif

35

Use Polymorphism
z

Little policy classes are an extension of the little


operations idea. Smaller rules are easier to read.

context LargeRegularLemonade::basePrice() : Money


body: Money::newInstance(2.43, Currency::USDollars)

z
z

context SmallFlavoredLemonade::basePrice() : Money


body: Money::newInstance(1.72, Currency::USDollars)

OCL Notes

z
z
z

Attach notes containing OCL to correct contexts.


OCL is visible in the diagrams.
Potential to clutter the model.

36

OCL and Class Diagrams


z
z
z
z
z
z
z
z
z
z

Derivation rules
Initial values
Body of query operations
Invariants
Pre- and post-conditions
Messaging in postconditions
Cycles in class models
Defining derived classes
Dynamic and optional multiplicity
Or constraints

Specifying Operations

37

OCL Resources
z

The Object Constraint Language, 2ed


Jos Warmer and Anneke Kleppe

OCL 2.0 Specification at OMG


http://www.omg.org/cgi-bin/doc?ptc/200310-14

38

Potrebbero piacerti anche