statecharts and object orientation everything you always wanted to know –but were afraid to ask

39
Statecharts and Object Orientation • Everything you always wanted to know – But were afraid to ask

Post on 19-Dec-2015

213 views

Category:

Documents


0 download

TRANSCRIPT

Statecharts and Object Orientation

• Everything you always wanted to know – But were afraid to ask

active

modeservice

active

quick

intense

on

washing

rinsing

dryingopen

off

normal>

faulty

H

DONE

DONE

evMode

evMode

tm(1000)/--dryTime;

tm(1000)/--rinseTime;

tm(1000)/--washTime;

[isDried()]/cycles++;evClose

evStart[IS_IN(normal)]/setup();

evOpen

[isInNeedOfService()]

evService

evService

Transitions• Default Transition

– No events or conditions

– Can have actions

• Regular transition– Event[condition]/action

– tm() is an event

• Null transition– [condition]

Default Transition

active

/count=10;print("started");

Regular Transition

active idleidleactive evGo[ready]/doit();

active idleidleactive evGo[ready]/doit();

What happens when evGo is taken?

• Condition is evaluated– Is ready true?

• If condition is true, actions on exit from state active are executed– In this case there aren’t any

• object exits state “active” • actions on transition are executed

– /doit()

• object enters state “idle”• Object executes action on entry to state “idle”

– In this case there aren’t any

timeout

rinsingrinsing

tm(1000)/--rinseTime;

• object enters state “rinsing”

• timer is set: set tm(1000)

• tm(1000) occurs 1000 ms later

Null Transition

isRinsed() is a guard on null transition

isRinsed() is evaluated every time object takes event

rinsing washing[isRinsed()]

rinsing washing

tm(1000)/--rinseTime

[isRinsed()]

/rinseTime=2;

Timeout with Null Transition

isRinsed() is a guard on null transition

Boolean isRinsed() {return(0==rinseTime);}

isRinsed() is evaluated every time tm(1000) occurs

If “rinsing” is entered for the first time at 0000, at what time(s) is isRinsed() invoked?

Timeout with guarding Condition

If “rinsing” is entered for the first time at 0000, at what time(s) is isRinsed() invoked?

rinsing washingC

[else]/--rinseTime

[isRinsed()]

/rinseTime=2;

tm(1000)

What happens in a state?

Or-states (1)

quickMode>

normalMode>

intensiveMode>quickMode>

normalMode>

intensiveMode>

evNormal

evNormal

evQuickevQuick

evIntensive

evIntensive

idle

running

pulsingspraying

evJ etPulseevJ etOffevJ etSpray

Or-states (2)-transition from superStates

• Object is in state “pulsing”

• Object takes event “evJetOff”

• What happens?

Or-states (3)-transition to superStates

• Object is in state “idle”

• Object takes event “evX”

• What happens?

idle

running

pulsingspraying

evJ etPulseevJ etOffevJ etSpray evX

Or-states (4)-transition to history

• Object is in state “rinsing”

• Object takes event “evOpen”

• What happens?• Object takes event• “evClose”• What happens?

activeactive

idle

busy

polling

evGo

tm(3000)

tm(2000)/GEN(evGo)

and-states(1)

event generated in one state, used in another • What is the

default state of the object?

• If startBehavior finished at 0000, what happens between 0000 and 7000?

active

runningmaintenance

mode

active

doorOpened>

doorClosed

filling>

rinsing>

washing>

draining>

off>

drying>

maintenanceOk>

maintenanceRequired>

quickMode>

normalMode>

intensiveMode>

DONE

DONE

H

tm(dryTime)

evFull

tm(washTime)

tm(rinseTime)

evStart/setup();

evEmpty

evOpen

evClose

evService[isInNeedOfService()]

evService

evNormal

evNormal

evQuickevQuick

evIntensive

evIntensive

and-states(2)what is default state?

Events sent between objects

full>

draining

empty>

filling

tm(4000)/itsDishwasher->GEN(evFull);

tm(4000)/itsDishwasher->GEN(evEmpty); evTankDrain

evTankFill

fillingoff rinsing

evStart/itsTank->GEN(evFill)

evFull

Dishwasher

TankDishwasher takes event evStart.

What happens?

Tracer Commands• output

– output mytrace.txt

• timestamp– OMTracer (0:00:00.000)

• go– Run

• go idle– takes next event in queue

– if no event in queue, but there is a scheduled timeout, advances clock and takes timeout event

Tracer Messages (1)• Invoked

– Dishwasher[0] Invoked isInNeedOfService()

• Returned– Dishwasher[0]->isInNeedOfService() Returned

• set tm()– Dishwasher[0] set tm(10000) at ROOT.active.running.doorClosed.rinsing

• Sent Event– Dishwasher[0] Sent to AcmeTank[0] Event evTankFill()

• Received Event– AcmeTank[0] Received from Dishwasher[0] Event evTankFill()

• Note: object can send event to itself– AcmeTank[0] Sent to itself Event tm(4000) at ROOT.filling– AcmeTank[0] Received from itself Event tm(4000) at ROOT.filling

• Object entered state– Dishwasher[0] Entered State ROOT.active

• Object exited state– Dishwasher[0] Exited State ROOT.active.mode.normalMode

Tracer Messages (2)• object cancelled timeout

– AcmeJet[0] cancelled tm(1000) at ROOT.running.pulsing.left

– When does this occur?

• Object modified Attribute values – Dishwasher[0] Modified Attribute Values

dryTime 3000

washTime 8000

cycles 1

rinseTime 10000

Start Behavior (1)

• Object enters root state – Display[0] enters ROOT

• Object enters each sub-state– Display[0] enters ROOT.active

• For each state entered, object executes entry actions (if there are any)

• Object executes actions on default transition (if there are any)

Start Behavior (2)

• If the initial state has an exit transition triggered by timeout:– Object does set tm() when state entered

• If there is a state with a null transition:– Object sends OMStartBehaviorEvent– After StartBehavior finishes, object receives

OMStartBehaviorEvent, and evaluates the condition on the null transition.

StartBehavior-countdown

OMTracer (0:00:00.000) main() Invoked Display[0]->Start Behavior

OMTracer (0:00:00.000) Display[0] Entered State ROOT

OMTracer (0:00:00.000) Display[0] Invoked print(string = started)

OMTracer (0:00:00.000) Display[0]->print(string = started) Returned

OMTracer (0:00:00.000) Display[0] Entered State ROOT.active

OMTracer (0:00:00.000) Display[0] set tm(200) at ROOT.active

OMTracer (0:00:00.000) Display[0]->Start Behavior Returned

StartBehavior-dishwasherOMTracer (0:00:00.000) main() Invoked Dishwasher[0]->Start BehaviorOMTracer (0:00:00.000) Dishwasher[0] Entered State ROOTOMTracer (0:00:00.000) Dishwasher[0] Entered State ROOT.activeOMTracer (0:00:00.000) Dishwasher[0] Entered State ROOT.active.runningOMTracer (0:00:00.000) Dishwasher[0] Entered State ROOT.active.running.doorClosedOMTracer (0:00:00.000) Dishwasher[0] Entered State ROOT.active.running.doorClosed.offOMTracer (0:00:00.100) Dishwasher[0] Entered State ROOT.active.modeOMTracer (0:00:00.100) Dishwasher[0] Entered State ROOT.active.mode.normalModeOMTracer (0:00:00.100) Dishwasher[0] Entered State ROOT.active.maintenanceOMTracer (0:00:00.100) Dishwasher[0] Entered State ROOT.active.maintenance.maintenanceOkOMTracer (0:00:00.100) Dishwasher[0] Sent to itself Event OMStartBehaviorEventOMTracer (0:00:00.100) Dishwasher[0]->Start Behavior ReturnedOMTracer (0:00:00.100) Dishwasher[0] Modified Attribute Values modeRinseTime 10000 modeWashTime 20000 modeDryTime 5000

After Start Behavior returns-dishwasher takes OMStartBehavior Event

(0:00:00.100) Dishwasher[0] Received from itself Event OMStartBehaviorEvent

(0:00:00.100) main() Invoked Dishwasher[0]->Take Event OMStartBehaviorEvent()

(0:00:00.100) Dishwasher[0] Invoked isInNeedOfService()

(0:00:00.100) Dishwasher[0]->isInNeedOfService() Returned

(0:00:00.100) Dishwasher[0]->Take Event OMStartBehaviorEvent() Returned

Take event-countdown

Take event-countdown(1)first cycle

Please enter OMTracer Command>> go idle

OMTracer (0:00:00.200) Display[0] Sent to itself Event tm(200) at ROOT.active

OMTracer (0:00:00.200) Display[0] Received from itself Event tm(200) at ROOT.active

OMTracer (0:00:00.200) main() Invoked Display[0]->Take Event Timeout

OMTracer (0:00:00.200) Display[0] Invoked isDone()

OMTracer (0:00:00.200) Display[0]->isDone() Returned

OMTracer (0:00:00.200) Display[0] Exited State ROOT.active

OMTracer (0:00:00.200) Display[0] Invoked print(n = 1)

OMTracer (0:00:00.200) Display[0]->print(n = 1) Returned

OMTracer (0:00:00.200) Display[0] Entered State ROOT.active

OMTracer (0:00:00.200) Display[0] set tm(200) at ROOT.active

OMTracer (0:00:00.200) Display[0]->Take Event Timeout Returned

Executable is Idle

Take event-countdown(2)termination

Please enter OMTracer Command>> go idleOMTracer (0:00:00.400) Display[0] Sent to itself Event tm(200) at ROOT.activeOMTracer (0:00:00.400) Display[0] Received from itself Event tm(200) at ROOT.activeOMTracer (0:00:00.400) main() Invoked Display[0]->Take Event TimeoutOMTracer (0:00:00.400) Display[0] Invoked isDone()OMTracer (0:00:00.400) Display[0]->isDone() ReturnedOMTracer (0:00:00.400) Display[0] Exited State ROOT.activeOMTracer (0:00:00.400) Display[0] Invoked print(n = 0)OMTracer (0:00:00.400) Display[0]->print(n = 0) ReturnedOMTracer (0:00:00.400) Display[0] Invoked print(string = Done)OMTracer (0:00:00.400) Display[0]->print(string = Done) ReturnedOMTracer (0:00:00.400) Display[0] Reached Termination StateOMTracer (0:00:00.400) Display[0]->Take Event Timeout ReturnedOMTracer (0:00:00.400) main() Invoked Display[0]->~Display()OMTracer (0:00:00.400) Display[0]->~Display() ReturnedOMTracer (0:00:00.400) Instance Display[0] of class Display deleted by main() Executable is Idle

off filling> rinsingevFull

evStart/setup(); state filling:

action on entry:itsTank->GEN(evTankFill)

Take event-dishwasherDishwasher takes evStart

full>

draining

empty>

filling

tm(4000)/itsDishwasher->GEN(evFull);

tm(4000)/itsDishwasher->GEN(evEmpty); evTankDrain

evTankFill

Take event-dishwasher(1)Dishwasher takes evStart

Please enter OMTracer Command>> go idleOMTracer (0:00:00.100) <user via GUI> Sent to Dishwasher[0] Event evStart()OMTracer (0:00:00.100) Dishwasher[0] Received from <user via GUI> Event evStart() Executable is IdleOMTracer (0:00:00.100) main() Invoked Dishwasher[0]->Take Event evStart()OMTracer (0:00:00.100) Dishwasher[0] Exited State

ROOT.active.running.doorClosed.offPlease enter OMTracer Command>> go idleOMTracer (0:00:00.100) Dishwasher[0] Invoked setup()OMTracer (0:00:00.100) Dishwasher[0]->setup() ReturnedOMTracer (0:00:00.100) Dishwasher[0] Modified Attribute Values dryTime 3000 washTime 8000 cycles 1 rinseTime 10000

OMTracer (0:00:00.100) Dishwasher[0] Entered State

ROOT.active.running.doorClosed.fillingOMTracer (0:00:00.100) Dishwasher[0] Sent to AcmeTank[0] Event evTankFill()OMTracer (0:00:00.100) Dishwasher[0] Invoked isInNeedOfService()OMTracer (0:00:00.100) Dishwasher[0]->isInNeedOfService() ReturnedOMTracer (0:00:00.100) Dishwasher[0]->Take Event evStart() Returned

Take event-dishwasher(2)Dishwasher takes evStart

OMTracer (0:00:00.100) AcmeTank[0] Received from Dishwasher[0] Event evTankFill()OMTracer (0:00:00.200) main() Invoked AcmeTank[0]->Take Event evTankFill()OMTracer (0:00:00.200) AcmeTank[0] Exited State ROOT.emptyOMTracer (0:00:00.200) AcmeTank[0] Entered State ROOT.fillingOMTracer (0:00:00.200) AcmeTank[0] set tm(4000) at ROOT.fillingOMTracer (0:00:00.200) AcmeTank[0]->Take Event evTankFill() Returned Executable is IdlePlease enter OMTracer Command>> go idleOMTracer (0:00:04.200) AcmeTank[0] Sent to itself Event tm(4000) at ROOT.fillingOMTracer (0:00:04.200) AcmeTank[0] Received from itself Event tm(4000) at

ROOT.fillingOMTracer (0:00:04.200) main() Invoked AcmeTank[0]->Take Event TimeoutOMTracer (0:00:04.200) AcmeTank[0] Exited State ROOT.fillingOMTracer (0:00:04.200) AcmeTank[0] Sent to Dishwasher[0] Event evFull()OMTracer (0:00:04.300) Dishwasher[0] Received from AcmeTank[0] Event evFull()OMTracer (0:00:04.300) main() Invoked Dishwasher[0]->Take Event evFull()OMTracer (0:00:04.300) Dishwasher[0] Exited State

ROOT.active.running.doorClosed.fillingOMTracer (0:00:04.300) Dishwasher[0] Entered State

ROOT.active.running.doorClosed.rinsing

Sequence Diagrams

• System Line (for main)

• Instance lines (for each object)

• Time goes from top to bottom

• Events- slanted line between objects

• Operations- horizontal line between objects

• object can send to itself– Events, operations, timeouts

countdown

Sequence Diagram-countdown

off filling> rinsingevFull

evStart/setup(); state filling:

action on entry:itsTank->GEN(evTankFill)

Dishwasher

full>

draining

empty>

filling

tm(4000)/itsDishwasher->GEN(evFull);

tm(4000)/itsDishwasher->GEN(evEmpty); evTankDrain

evTankFill

Sequence Diagram-dishwasher(1)

Sequence Diagram-dishwasher(2)