0% found this document useful (0 votes)
90 views

Coding With UML

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
90 views

Coding With UML

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 103

Coding with UML

Stephen J. Mellor
What’s the problem?

1
A simple embedded system
 Set the time,
 Close the door,
 Press ‘cook’
 It’s that easy!
But…..
 For safety, the door must be closed
 If the door is opened, cooking must stop.
 There are some details about timers
 And power levels……
 And…. And…. And….
Complex Systems
• We want to be able to:
– Develop concepts rapidly
– Test ideas with confidence
– Reduce required code by
identification of cross-cutting
commonality
– Understand performance
before implementation
– Adapt easily to hardware and
platform changes
– Maximize parallel development
Abstraction
Price Performance System Complexity
High Level
Assembly UML Models
Language

Compiler Model
Assembler
Compiler

Machine High Level


Code Assembly Language

1980s 1990s 2000s

Increased
Productivity
Testing
• Systems are difficult to test—and it occurs too
late.
– Wasted effort in constructing wrong code
– Late discovery of problems and delayed delivery
What we get
What we’d like

Defect
Rate

Specification Analysis Design Test & Integration Deployment


Skills
• Large designs require specialization of skills.
A solution is…
• We need to specify systems in a language that is:
– Concurrent: assume the system is distributed
– Complete: not a blueprint to be filled in
– Executable, and
– Translatable: so the specification can be mapped
into an implementation.

Mapping

The knowledge The software


Why?
• Why are concurrent specifications
necessary?
– Because our problems are concurrent
– Concurrency problems exist in the problem as
well as the implementation.
– So we can establish priorities among tasks
– So we can maximize precious system resources
when many things can happen at once.
Coding Data in UML

2
Code for a Microwave Oven
struct Oven_s {
UniqueID_t OvenID; /* * OvenID */

/* Association storage */
Door_s * Door _R1;
Cooking_Step_s * Cooking_Step _R2;
Cooking_Step_s * Cooking_Step_R3;
Magnetron_s * Magnetron_R4;

/* State machine current state */


StateNumber_t current_state;
};
Another Piece of Code
struct Cooking_Step_s {
i_t stepNumber; /* * StepNumber */
i_t cookingTime; /* - cookingTime */
i_t powerLevel; /* - powerLevel */
Timer_t * executionTimer; /* - executionTimer
*/

/* Association storage */
Oven_s * Oven_R2;
Oven_s * Oven_R3;

/* State machine current state */


StateNumber_t current_state;
};
The Code Follows Rules
struct <class name>_s {
<attr1 type> <attr1 name>; /* <attr1 description> */
<attr2 type> <attr2 name>; /* <attr2 description> */
<attr2 type> <attr2 name>; /* <attr2 description> */
. . .
/* Association storage */
<ref1 class name>_s * < ref1 class name >_<assoc1 number>;
<ref2 class name>_s * < ref2 class name >_<assoc2 number>;
. . .
/* State machine current state */
StateNumber_t current_state;
};
Class Diagram
Abstract classes based on both:
 Data
 Behavior
R1
Door

isOpen
R2 Cooking Step
Oven
R3
stepNumber
cookingTime
Magnetron powerLevel
R4

powerOutput
pulseTimer
Associations
• Classes may be associated to capture
relationships in the subject matter.
• We number the relationships to ensure
uniqueness.
describes first
R2 Cooking Step
parameters for executes first
Oven
R3
stepNumber
cookingTime
describes second executes second
powerLevel
parameters for
Association Classes
• Some associations give rise to other classes.
Font Table

fontName:string
Loaded Font
*
R5 fontName:string
* printerID:string

Logical Printer

printerID:string
current_state:state<State_Model>
Generalization
• One class may be a supertype of others.
follows
Allocated Job
R3
printerID:string
jobNumber:integer 0...1

{disjoint, preceeds
R2 Complete}

In Work Job Held Job

printerID:string printerID:string
jobNumber:integer jobNumber:integer
Class Diagram
Abstract classes based on both:
 Data
 Behavior

R1
Door

isOpen
R2 Cooking Step
Oven
R3
stepNumber
cookingTime
Magnetron powerLevel
R4

powerOutput
pulseTimer
Coding Behavior in UML

3
State Event Matrix for the Oven
static const StateNumber_t Oven_StateEventMatrix[3][4] =
{
/* Row 1: Oven_State_1 'Not_Cooking' */
{ Oven_State_2, CANT_HAPPEN, IS_IGNORED, IS_IGNORED },
/* Row 2: Oven_State_2 'Checking_Safety' */
{ Oven_State_2, Oven_State_3, IS_IGNORED, IS_IGNORED },
/* Row 3: Oven_State_3 'Cooking' */
{ CANT_HAPPEN, CANT_HAPPEN, Oven_State_3, Oven_State_1 }
};
…and the Cooking Step
static const StateNumber_t Cooking_Step_StateEventMatrix[3][3] =
{
/* Row 1: Cooking_State_1 'Ready' */
{ Cooking_State_2, IS_IGNORED, Cooking_State_3 },
/* Row 2: Cooking_State_2 'Executing' */
{ IS_IGNORED, Cooking_State_1, Cooking_State_3 },
/* Row 3: Cooking_State_3 'Complete' */
{ IS_IGNORED, IS_IGNORED, IS_IGNORED }
};
Lifecycles
Build a lifecycle model
for each class.
Ready

startStep
interrupt

Executing
Lifecycle for
Cooking Step finishStep
finishStep

Complete
State Event Matrix for Oven

Signal
start cook step_done stop
State
CANT CANT
Not Cooking Checking IGNORED
HAPPEN HAPPEN
CANT
Checking Checking Cooking IGNORED
HAPPEN
CANT CANT
Cooking Cooking Not Cooking
HAPPEN HAPPEN
Event dispatching code for the Oven
. . .
state = instance->current_state;
next_state = Oven_StateEventMatrix[ state ][ event_number ];
if ( next_state <= 3 )
{
/* Update state and execute the state action */
instance->current_state = next_state;
( *Oven_Actions[ next_state ] )( instance, event );
}
. . .
… and for Cooking Step
. . .
state = instance->current_state;
next_state = Cooking_Step_StateEventMatrix
[ state ][ event_number ];
if ( next_state <= 3 ) {
/* Update state and execute the state action */
instance->current_state = next_state;
( *Cooking_Step_Actions[ next_state ] )( instance, event );
}
. . .
..and the rule to produce it
. . .
state = instance->current_state;
next_state = <class name>_StateEventMatrix
[ state ][ event_number ];
if ( next_state <= <class num_states> )
{
/* Update state and execute the state action */
instance->current_state = next_state;
( *<class name>_Actions[ next_state ] )( instance, event );
}
. . .
Constructing the State Event Matrix
static const State_Number_t <class name>_StateEventMatrix
[<class states>][<class events>] =
{
/* Row <state1 number>: <state1 name> */
{ <state1event1 next_state number>,
<state1event2 next_state number>, . . . }
/* Row <state2 number>: <state2 name> */
{ <state2event1 next_state number>,
<state2event2 next_state number>, . . . }
. . .
};
Coding Communication in UML

4
Instances

An executable model operates


on data about instances.

Recipe
Recipe Recipe Cooking Cooking Heating
Name Time Temp Rate
Recipe Name {I}
Batch Nylon 23 200 2.23
Cooking Time Batch
Kevlar 45 250 4.69
Cooking Temperature Batch ID Amount of Recipe
Batch ID {I} Stuff 67 280 1.82 Status
Heating Rate Batch Name
Amount of Batch
Recipe Name {R2} 1 100 Nylon Filling
Status 2 127 Kevlar Emptying
3 93 Nylon Filling
4 123 Stuff Cooking
Executing the Model

• The model executes in


response to signals from:
– the outside, Ready

startStep
interrupt

Executing
– timers finishStep
finishStep

Complete

– other instances as
they execute
Instances
• An executable model Ready

operates on instances. startStep


interrupt
Executing

finishStep
finishStep
Complete

Oven

Not Cooking
start
start Ready

startStep
interrupt
Checking
finish_step Executing
stop cook
finishStep
finishStep
Cooking
Complete
How does time work….?
– There is no global clock
– Time is relative to each observer

© 2005 Model Integration, LLC


Concurrent Execution
All instances execute concurrently.
Oven
Not Cooking
start
start

Checking
cook finish_step
stop

Cooking

Cooking Step 1 Cooking Step 2

Ready Ready

startStep
startStep interrupt interrupt
Executing
Executing
finishStep finishStep
finishStep finishStep

Complete Complete
Communication
Oven Cooking Step 2

Not Cooking Ready


start
start startStep
interrupt
Checking Executing
cook finish_step
stop finishStep
finishStep
Cooking Complete

Oven Before and Cooking Step 2


after.
Ready
Not Cooking
start startStep
start interrupt
Executing
Checking
finish_step finishStep
cook finishStep
stop
Complete
Cooking
Coding Logic in UML

5
Coding Logic in UML

/* SELECT ONE magnetron RELATED BY oven->MW_MT[R4] */


v89_magnetron = v84_oven->mc_MW_MT_R4;
/* ASSIGN magnetron.powerOutput = SELF.power_level */
v89_magnetron->m_powerOutput = self->m_power_level;
/* GENERATE MW_MT1:'power_on'() TO magnetron */
{
OoaEvent_t * event90 = NewOoaEvent(
(void *) v89_magnetron, &MO_MW_MT_Event1_sc );
SendEvent( event90 );
}
Activity
• Progression of the state machines causes execution of an
activity.

• The activity is written in an action language.

select one magnetron related by oven->[R4]; Selection


Assignment
magnetron.powerOutput = self.powerLevel;
Signal
generate powerOn to magnetron; Generation

• Each statement may be translated into code in different


ways, depending on choice of data and control structure.
Activities
 There is one activity for each state in the state
machine
 Each state machine is one state at a time
 All actions in the activity must terminate before the
next state can be entered

This is commonly called run-to-completion semantics


Executable elements
 Data
 Control
 Processing

Class Model State Models Activity Models


select one magnetron
objectC

related by oven->[R4];
objectB

magnetron.powerOutput =
self.powerLevel;
objectA
generate powerOn to
magnetron;

Class Diagram State Charts Action Language


Three Primary Diagrams
Class Diagram
Oven Cooking Step
R2
powerLevel Statechart Diagram
cookingTime

Action Language

Executing
Lifecycle for Ready
Cooking Step startStep Entry/
Executing
select one magnetron
finishStep related by oven->[R4];
Complete magnetron.powerOutput =
self.powerLevel;
generate powerOn to magnetron;

Action for state Executing


xtUML
Actions State

Sequence Diagrams

Diagrams

Class
Diagrams

Communcation
Diagrams
xtUML
xtUML is a streamlined subset of the UML
industry standard that:
(x) Executes models
– Allows for early verification

– Integration of legacy code

(t) Translates models


– Complete code generation
from models
– Customizable compilation rules

– Optimized code
Completing the Models

6
Timers
To build an implementation, we will use timers.

Magnetron Tube 1. OFF

magnetronID:arbitrary_id
powerOutput;integer
pulseTimer:inst_ref<Timer>

2. PulseON 2. PulseOFF
Timers are generally provided.
Timers
<<external entity>>
SecondsTimer
<operation>
timer_start(seconds : integer, event_inst : inst<Event>) : inst_ref <Timer>
timer_cancel(timer_inst_ref : inst_ref<Timer>) : boolean
timer_remaining_time(timer_inst_ref : inst_ref<Timer>) : integer

<<operation>>
current_date : date
create_date(second : integer,minute : integer,hour : integer,day : integer,month : integer, year
get_second(date : date) : integer
get_minute(date : date) : integer
get_hour(date : date) : integer
current_clock : timestamp
timer_start(microseconds : integer, event_inst : inst<Event>) : inst_ref<Timer>
timer_reset_time(timer_inst_ref : inst_ref<Timer>, microseconds : integer) : boolean
timer_add_time(timer_inst_ref : inst_ref<Timer>, microseconds : integer) : boolean
timer_cancel(timer_inst_ref : inst_ref<Timer>) : boolean
Tying an instance of an Event to a Timer
3. PulseOFF

Entry/

Bridge PIO: :PulseOff();


3. PulseOFF // set up a timer to pulse on again

If self.powerOutput < 10
seconds_off = (10 –self.powerOutput);
create event instance pulseon of MW_MT3:’pulse_on’ to self;
self.pulseTimer = Bridge STIM::timer_start(seconds;seconds_off,
event_inst;pulseon);
end if;
Bridge to Hardware
We must also bridge to the hardware.

• Bridge PIO::PulseOff();

• // set up a timer to pulse on again

• If self.powerOutput < 10
• seconds_off = (10 - self.powerOutput);
• create event instance pulseon of W_MT3:'pulse_on' to self;
• self.pulseTimer = Bridge STIM::timer_start(
seconds:seconds_off, event_inst:pulseon);
• end if;
External Entities
The operations allow bridging from one domain to another.

<<external entity>> <<external entity>>


Control Panel Seconds Timer

<<operation>> <<operation>>
DisableKeyEntry : void timer_start(seconds : integer, event_inst : i…
EnableKeyEntry : void timer_cancel(timer_inst_ref : inst_ref<Time…
timer_remainging_time(timer_inst_ref : inst_r…
<<external entity>>
Process Input/Output <<external entity>>
Timer
<<operation>> <<operation>>
CookingOn : void current_date : date
CookingOff : void create_date(second : integer, minute : inte..
PulseOn : void get_second(date : date) : integer
PulseOff : void get_minute (date : date) : integer
Initialization
• select any oven from instances of MW_OV;
• If (empty oven)
• create object instance oven of MW_OV;

• create object instance door of MW_DR;


• relate door to oven across R1;
• assign door.isLocked = false;

• create object instance tube of MW_MT;


• relate tube to oven across R4;
• assign tube.powerOutput = 10;

• Bridge CP::EnableKeyEntry();
• // now that system is initialized
• end if;
Domain Package Diagram
– Application
– Proxies for
external <<external entity>>
entities <<subsystem>>
External Entities
– Datatypes Cooking Control

– Functions
<<data type>> <<function>>

Datatypes Functions
Mapping to an Implementation

7
Concurrency in the generated code
– An application is inherently concurrent except
insofar that it is purposefully sequenced
– xtUML captures necessary sequentialization in
the model.
– Model compilers translate the concurrent
specification onto an implementation of
concurrency.
So, what should the structure of that
implementation be?
Activities
• The basic unit of allocation is the activity.

• Here, we allocate all


activities to a Door closed
single task.
pulse ON
checking
Oven safety
Magnetron

Oven cooking

pulse OFF
executing

Cooking Magnetron
Step
Activities
• Each activity is caused to execute on receipt of a signal.

Door closed
Door closed

pulse ON
• What happens next? Oven checking
safety
Magnetron

Oven cooking

pulse OFF
executing

Cooking Magnetron
Step
Dequeuing Signals
• When a signal is received, we:
– Determine what to do next based on the
name of the signal and the current state
– Do it
Oven
Signal
start cook step_done stop
State
Not Cooking
CANT CANT start
Not Cooking Checking IGNORED
HAPPEN HAPPEN start

CANT Checking
Checking Checking Cooking IGNORED
HAPPEN step_done
stop cook
CANT CANT
Cooking Cooking Not Cooking
HAPPEN HAPPEN Cooking
Communication
• If actions generate signals to other objects, we:
– Store the new signals
on an internal queue
Door
– Pick them off closed

one by one
checking
– When the queue Oven safety

is empty, wait for


another signal Oven cooking

executing

Cooking
Step
External Communication
Door closed

checking
Oven safety

– Each task receives


signals and queues them Oven cooking

– Each task executes all the


processing associated executing
with the receipt of a Cooking
single signal Step

– Internal and external


signals are the same
Priority in a Task
• Events can be assigned a priority within a
single task.

Ready
NotCooking startStep
interrupt
start
Executing
Checking
stop cook finishStep
finishStep
Cooking Complete
Single Tasking Concurrency
• Concurrency is simulated, but:
– The “granularity of concurrency” is an activity
– An activity must wait for another to finish
– The waiting activity may be higher priority
=> Priority inversion
A Direct Mapping
We may map each class to a separate task.
Cooking Step
Oven
Ready
Not Cooking
start startStep interrupt
start
Executing
Checking
finishStep finishStep
stop cook
Complete CookingStep
Cooking Oven

Oven checking Cooking Ready


safety Step

Oven cooking Cooking executing


Step
Map Multiple Classes Cooking Step
Ready

Door startStep interrupt


closed
Executing
finishStep finishStep
pulse ON Complete
Oven checking
safety
Magnetron Oven
Not Cooking
start
Oven start
cooking
Checking
stop cook
Cooking
Cooking executing pulse OFF
Step
Magnetron • We may map
multiple classes to a
single task.
Multi-Tasking Concurrency
For this mapping, we choose to allocate classes.
R1
Door

isOpen

R2 CookingStep
Oven
stepNumber
cookingTime
powerLevel
R3

Magnetron
R4
powerOutput
pulseTimer
Multi-Tasking Concurrency
For this mapping, we choose to allocate classes.

CookingStep
Door
stepNumber
isOpen
cookingTime
powerLevel
Oven
Magnetron

powerOutput
pulseTimer
More information for translation
• We need also to state:
– Priorities of tasks
– Which classes go in which classes

• .invoke EnableTasking( “Nucleus”, 2)


• .invoke SetTaskPriority( 1, “low” )
• .invoke SetTaskPriority( 2, “high” )

• .invoke MapClassToTask( “OvenControl”, “Door”, 1 )


• .invoke MapClassToTask( “OvenControl”, “Oven”, 1 )
• .invoke MapClassToTask( “OvenControl”, “Magnetron”, 2
)
• .invoke MapClassToTask( “OvenControl”, “CookingStep”,
2 )
Mappings

8
Separation
Application

• Design can be split between:


Oven Magnetron

• Subject matter experts who


Ready

Executing
Entry/
Select one magnetron
Executing
understand the application,
and
related by oven->[R4];
Magnetron. powerOutput=
self.powerLevel;
Generate powerOnto magnetron;
Complete

• Experts who understand the


application-independent
Checking

architecture
Checking

Checking Settings
Entry/
OpenShutter( 0.5 );
• Each evolves at its own pace.
MeasureLight();

Architecture
Mappings
• Mapping by hand:
– Is error prone
– Not repeatable
– Not scalable
– Not predictable
– Leads to integration problems

Mapping

The knowledge The software


Integration
• Large systems are difficult to integrate.

vs.
Scale
• The cost of a design rises steeply as system size increases.

Integration costs

Reuse benefits

Number of classes
Reuse
• Designs are difficult to reuse.
Retargeting
• Designs are difficult to retarget.
Instrumentation and Diagnosis
• Designs are difficult to instrument and diagnose.
Optimization
• Large designs are difficult to optimize reliably.
Model Compilers

9
Model Compiler
• A set of rules: Translation
rules interpreted by a
generator against the Rules
repository

• An execution engine: A
limited set of reusable
components sufficient to
Reusable library
execute Executable UML
Purpose

• To generate code….
Miracle
occurs here

Model Database
Application Models
Class
Code for the
Class ID Name Descr'n
System
100 Oven .....
101 Door .....State
Class ID State # Name
101 1 Ready
101 2 Executing
Purpose
• ….traverse the model database and...

Class State Chart


R13
Class ID 1 0..1
Class ID {R13}
Name Name
Description
1
R14
1..*

State … output text.


Class ID {R14}
State Number
Name
Example
The rule language produces text.
.select many stateS related to instances of
class->[R13]StateChart ->[R14]State
where (isFinal == False)
public:
enum states_e public:
enum states_e
{ NO_STATE = 0 ,
{ NO_STATE = 0 ,
.for each state in stateS Ready ,
.if ( not last stateS ) Executing ,
${state.Name } , NUM_STATES = Complete
.else };
NUM_STATES = ${state.Name}
.endif
.endfor
};
Building the System
Marks
Model Compiler

Rules

Application Models
Model Database
Class
Class ID Application
Name Descr'n Models
100 Oven .....State Generator Reusable Library
101 Door
Class ID.....
State # Name
101 1 Ready
101 2 Executing

• Libraries, Legacy or
• Hand-written code
Code for
the System
Model Compiler
• An architecture is an Executable UML model compiler.

It translates a system specified in executable UML into


the target programming language incorporating
decisions made by the architect about:

– data
– control
– structures
– time

Model compilers, like programming


languages compilers, can be bought.
Model Debugging

10
Models Execute on Instances
Execution Control
Execution
Coding with UML Models

11
Model it!
name name

Model the Application

name name name


Mark it!
Task A Task B

name name

Assign Classes to Tasks

Task A Task B Task A


name name name
Make it!
Task A Task B

name name

Task A Task B Task A


name name name
Profile it!

 Analyze the
performance

 Not as good as
you need?
Re-Mark it!
Task A Task B

name name

Reassign Classes to Different


Tasks

Task A Task A
B Task A
B

name name name


Make it Again!
Task A Task B

name name

Task A Task A Task B

name name name


Translative System Generation
• Translative System Generation is a system-
construction method based on:

 separating systems into


subject matters (domains)
 specifying each domain with
an executable model
 translating the models
according to a set of rules
Integration
• (Properly tested) rules guarantee the pieces will integrate.

vs.
Testing
• Executable models can be tested early

What we now get What we got

Defect
Rate

Specification Analysis Design Test & Integration Deployment


Scale
The cost of a design remains the same for a given model
compiler.

Unscalable approaches

Variable costs of applying


the model compiler

Fixed costs of model compiler

Number of classes
Reuse
Designs can be reused.

Application Models
Retargeting
Designs can be re-targetted by selecting a different
model compiler.
Instrumentation and Diagnosis
Designs are instrumented and diagnosed in one place:
the model compiler.
Optimization
Optimization is propagated throughout the system
reliably using automated rules.
Skills
• Application experts worry about the
application…

• ...while architects worry about the


architecture.
Translative System Generation
Translative system generation meets the challenges
of real-time software development by:

 localizing critical software design issues to the


software architecture domain
 ensuring that the design decisions are incorporated
uniformly and systematically
 providing a framework to modify system
performance without affecting system behavior

In other words, it sca les.


Want to learn more?
Executable UML: A Foundation Executable UML: How to
for Model-Driven Architecture, Build Class Models, Leon
Stephen J. Mellor, Marc Balcer Starr
Practical guide for model
developers.
Comprehensive language introduction and
reference

MDA Distilled: Principles of Executable UML: A


Model-Driven Architecture, Case Study, Leon Starr
Stephen J. Mellor, Kendall Scott,
Axel Uhl, Dirk Weise
A complete set of models on CD
A description of how this technology that you can execute.
fits in to Model-Driven Architecture

You might also like