Vous êtes sur la page 1sur 536

Essentials of IBM Rational Rhapsody v7.

5 for
Software Engineers (C++)
QQ136 June 2009
Student Manual
Volume 2
Part Number: 800-027571-000
IBM Corporation
Rational software
Essentials of IBM Rational Rhapsody v7.5 for Software Engineers (C++)
Student Manual Volume 2

June 2009

U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with
IBM Corp.

This information was developed for products and services offered in the U.S.A.

IBM may not offer the products, services, or features discussed in this documentation in other countries. Consult your local
IBM representative for information on the products and services currently available in your area. Any reference to an IBM
product, program, or service is not intended to state or imply that only that IBM product, program, or service may be used.
Any functionally equivalent product, program, or service that does not infringe any IBM intellectual property right may be
used instead. However, it is the user's responsibility to evaluate and verify the operation of any non-IBM product, program,
or service.

IBM may have patents or pending patent applications covering subject matter described in this document. The furnishing of
this document does not grant you any license to these patents. You can send license inquiries, in writing, to:
IBM Director of Licensing
IBM Corporation
North Castle Drive
Armonk, NY 10504-1785
U.S.A.

For license inquiries regarding double-byte (DBCS) information, contact the IBM Intellectual Property Department in your
country or send inquiries, in writing, to:
IBM World Trade Asia Corporation
Licensing
2-31 Roppongi 3-chome, Minato-ku
Tokyo 106-0032, Japan

The following paragraph does not apply to the United Kingdom or any other country where such provisions are
inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS
PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR
FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in certain
transactions, therefore, this statement may not apply to you.

This information could include technical inaccuracies or typographical errors. Changes are periodically made to the
information herein; these changes will be incorporated in new editions of the publication. IBM may make improvements
and/or changes in the product(s) and/or the program(s) described in this publication at any time without notice.

Any references in this information to non-IBM Web sites are provided for convenience only and do not in any manner serve
as an endorsement of those Web sites. The materials at those Web sites are not part of the materials for this IBM product and
use of those Web sites is at your own risk.

Licensees of this program who wish to have information about it for the purpose of enabling: (i) the exchange of information
between independently created programs and other programs (including this one) and (ii) the mutual use of the information
which has been exchanged, should contact:
Intellectual Property Dept. for Rational Software
IBM Corporation
20 Maguire Road
Lexington, Massachusetts 02421-3112
U.S.A.
Such information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee.

The licensed program described in this document and all licensed material available for it are provided by IBM under terms
of the IBM Customer Agreement, IBM International Program License Agreement or any equivalent agreement between us.

Any performance data contained herein was determined in a controlled environment. Therefore, the results obtained in other
operating environments may vary significantly. Some measurements may have been made on development-level systems and
there is no guarantee that these measurements will be the same on generally available systems. Furthermore, some
measurements may have been estimated through extrapolation. Actual results may vary. Users of this document should verify
the applicable data for their specific environment.

Information concerning non-IBM products was obtained from the suppliers of those products, their published announcements
or other publicly available sources. IBM has not tested those products and cannot confirm the accuracy of performance,
compatibility or any other claims related to non-IBM products. Questions on the capabilities of non-IBM products should be
addressed to the suppliers of those products.

All statements regarding IBM's future direction or intent are subject to change or withdrawal without notice, and represent
goals and objectives only.

This information contains examples of data and reports used in daily business operations. To illustrate them as completely as
possible, the examples include the names of individuals, companies, brands, and products. All of these names are fictitious
and any similarity to the names and addresses used by an actual business enterprise is entirely coincidental.

If you are viewing this information in softcopy, the photographs and color illustrations may not appear.

Trademarks and service marks


IBM, the IBM logo, and ibm.com are trademarks or registered trademarks of International Business Machines Corp.,
registered in many jurisdictions worldwide. Other product and service names might be trademarks of IBM or other
companies. A current list of IBM trademarks is available on the Web at Copyright and trademark information at
www.ibm.com/legal/copytrade.html

Adobe, the Adobe logo, PostScript, and the PostScript logo are either registered trademarks or trademarks of Adobe
Systems Incorporated in the United States, and/or other countries.
IT Infrastructure Library is a registered trademark of the Central Computer and Telecommunications Agency which
is now part of the Office of Government Commerce
Intel, Intel logo, Intel Inside, Intel Inside logo, Intel Centrino, Intel Centrino logo, Celeron, Intel Xeon, Intel
SpeedStep, Itanium, and Pentium are trademarks or registered trademarks of Intel Corporation or its subsidiaries in
the United States and other countries.
Intel trademark information
Linux is a registered trademark of Linus Torvalds in the United States, other countries, or both.
Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United
States, other countries, or both.
Microsoft trademark guidelines
ITIL is a registered trademark, and a registered community trademark of the Office of Government Commerce, and
is registered in the U.S. Patent and Trademark Office
UNIX is a registered trademark of The Open Group in the United States and other countries.
Cell Broadband Engine is a trademark of Sony Computer Entertainment, Inc. in the United States, other countries, or
both and is used under license therefrom.
Java and all Java-based trademarks and logos are trademarks of Sun Microsystems, Inc. in the United States, other
countries, or both.

Other company, product, or service names may be trademarks or service marks of others.

Copyright IBM Corporation 2009


Essentials of IBM Rational Rhapsody v7.5 for Software Engineers (C++) Table of Contents

Contents
Introduction
Essential prerequisites .................................................................................................2
Course agenda..............................................................................................................3

Basic Rational Rhapsody


Setting up Rational Rhapsody .....................................................................................4
Exercise 1 : Hello World .............................................................................................7
Exercise 2: Count down.............................................................................................32
Properties ...................................................................................................................73
Exercise 3 : Dishwasher ............................................................................................90
Exercise 4: Dishwasher system................................................................................132

Case Study
Case study: Cash register.............................................................................................3
Use case 1: Configure the products ...........................................................................44
Use case 2: Keep track of selected products..............................................................88
Use case 3: Generate a ticket showing total cost .....................................................166
Use case 4: Manage special offers...........................................................................188

Advanced Rational Rhapsody


Triggered operations....................................................................................................4
Introduction to the Rational Rhapsody framework....................................................12
More about containers ...............................................................................................39
Managing interrupts...................................................................................................47
Generating reports .....................................................................................................50
Using the COM API ..................................................................................................57
Using the Java API ....................................................................................................63
Introduction to configuration management................................................................76
Introduction to Rational Rhapsody TestConductor ...................................................98
Stopwatch exercise ..................................................................................................112
Speed camera exercise.............................................................................................115
Useful tips................................................................................................................117
Avoiding common mistakes ....................................................................................122

Copyright IBM Corp. 2009 i


Course materials may not be reproduced in whole or in part without the prior written permission of IBM.
Essentials of IBM Rational Rhapsody v7.5 for Software Engineers (C++) Table of Contents

Page intentionally left blank.

Copyright IBM Corp. 2009 ii


Course materials may not be reproduced in whole or in part without the prior written permission of IBM.

IBM Software Group

Essentials of IBM Rational Rhapsody v7.5 for Software


Engineers (C++)
Introduction

2009 IBM Corporation


Essential prerequisites
This course is a 3 day hands-on introduction to the use
of Rational Rhapsody to build Object Oriented Real-
Time software.
It is assumed that you have a good understanding of
Object Oriented Analysis and Design using the UML, as
well as a good understanding of C / C++.
For the Rational Rhapsody in C / C++ courses, one of
the following compilers must be installed:
 MinGW ( http://www.mingw.org )
 Visual C++ V6.0 by Microsoft
 Visual Studio .NET 2003, 2005 or 2008 by Microsoft
 Cygwin ( http://www.cygwin.com )
 Borland bcc32 compiler ( www.borland.com )

2
Course agenda
The course is composed of three parts, each of which
generally takes about a day to complete:

Part 1: Basic Rational Rhapsody

Part 2: Case Study

Part 3: Advanced Rational Rhapsody

3
Part 1 : Basic Rational Rhapsody
The idea of day one is to get familiar with the
fundamentals of Rational Rhapsody.
You start with the simplest example possible, just a
single object that prints out Hello World.
Next, you create a simple counter using a single
class, a couple of attributes, some operations, and a
simple statechart.
Continuing using just a single class, you create a
dishwasher and a more complex statechart.
In the last example, you investigate simple relations,
by adding extra classes to our dishwasher.

4
Part 2: Case study
Now that you are familiar with the fundamentals, you
can start to develop a model that is more complex,
more interesting and more complete.
You will develop a single model starting from some
requirements for a simple stand-alone Cash
Register.
You will use an iterative use-case driven process
and will incorporate many more features as you
design the model, such as Profiles, Threads,
Packages, Ports, Qualified Associations, Interface
Classes, and so on.

5
Part 3: Advanced Rational Rhapsody
All the examples that you have done up to now have
had very precise instructions enabling you to learn
how to use Rational Rhapsody. Now you are going
to see if the basics have been understood, by
attempting to build a simple model such as a
Stopwatch without step by step instructions.
You will be given a short introduction to some very
important Specialist topics such as:
Configuration Management
The Rational Rhapsody Framework

IBM Software Group

Essentials of IBM Rational Rhapsody v7.5 for Software


Engineers (C++)
Basic Rational Rhapsody

2009 IBM Corporation


Agenda
Objectives
Setting up Rational Rhapsody in C++
Exercise 1 : Hello World
Exercise 2 : Count Down
Properties
Exercise 3 : Dishwasher
Exercise 4 : Dishwasher System
Summary

2
Objectives
At the end of this module, you will be able to:
 Create a new Rational Rhapsody project.
 Do some basic modeling using classes, attributes,
operations, relations and state charts.
 Generate and compile code.
 Set properties to customize the tool and the generated
code.
 Debug the model by injecting events, setting breakpoints,
capturing behavior on sequence diagrams, visualizing the
state of objects, and so on.

3
Setting up Rational Rhapsody
Install at least one of the following compilers:
Microsoft Visual C++ 6.0
MinGW (Note that your instructor can provide this
compiler as well as the necessary adapter)
Visual Studio .NET 2003, .NET 2005, .NET 2008
Cygwin
Install Rational Rhapsody in C++ V7.5
Install license (license.dat)
Create a work directory, for example, C:\Work

Depending on the compiler that


has been installed, you may
need to rebuild the Rational
Rhapsody framework.

4
Extra files
Before starting, ensure that you have obtained
the following files from your instructor. These
will be needed during the training course:

5
Before you start
Rational Rhapsody uses C++, which is case sensitive. Most of
the errors that are made during this training course are errors
in entering text.
During this training, you will use a naming convention where all
classes start with an upper case, and all operations and
attributes with a lower case. If two words are concatenated,
then the first letter of each word is capitalized, for example,
thisIsAnOperation, MyClass, anAttribute.
It may vary how long it takes you to complete the exercises.
For those who finish early, there are several Extended
Exercises that can be done.
There are several places where it is necessary to type several
lines of code / text. If you do not like typing, a cheat sheet is
available so text can be cut and pasted. During the exercises,
look for the following symbol, indicating that text can be cut
and pasted from the cheat sheet.
6
Exercise 1 : Hello World

7
Creating a project
Start Rational Rhapsody in C++ (development
edition).
Within Rational Rhapsody, either click or select
File > New or New Project to create a new project
called Hello in the directory C:\Work.

Make sure that the


project is saved into
the subdirectory with
the same name Hello
Click OK then Yes to save project. in directory C:\Work.

8
Browser
The browser shows you everything that is in the
model.
Note that Rational Rhapsody creates an Object Model
Diagram (OMD).

Object
model
diagram
Browser

9
Drawing a class
In this Object Model Diagram, click the Class icon
to draw a class named Display.
Show/Hide Drawing
Toolbar

Expand the
browser to see
that the class
Display also
appears in the
browser.

10
Remove from View / Delete from model
Two ways of deleting a class
Remove the class from the view
(this is what the Delete key
does).
Delete the class from the model.
If you use the delete key or
select Remove from View,
then the class Display is just
removed from this diagram,
but remains in the browser.
If you select Delete from
Model, then you must confirm
with Yes in order to remove
the class from the entire
model.

11
Adding a constructor
The simplest way to add a
constructor is to right-click on
the class and choose
Add New > Constructor.

You do not need any


constructor arguments;
click OK.

Constructors may also be


added through the
featuresOperations tab.
Click New and select
Constructor.

12
Display options
You would expect to see the
constructor shown on the class
on the Object Model Diagram.
You can control what gets
displayed on this view of the
class by using Display Options.
Right-click Display class and
select Display Options.
Set the options to display All
attributes and All operations.

13
Display constructor
You should be able to see the constructor is now
shown in both the browser and the OMD (object
model diagram).

Constructor

14
Adding an implementation
Select the Display constructor in the browser and
double-click to open the features window.
Select the Implementation tab and enter the
following:
cout << Hello World << endl;

If you are not using Visual C++


6.0, then you should add the
std namespace, for example,
std::cout << Hello
World << std::endl;
Or, set the property
CPP_CG::Class::Implementati
onProlog to using
namespace std;.

15
#include <iostream>
Since you have used cout,
you must add an include
of the iostream header to
the Display class.
In the browser, select the
Display class and double-
click to bring up the
features.
Select the Properties tab
Ensure that the Common
View is selected
Enter <iostream> into the
ImpIncludes property.

ImpIncludes is an abbreviation for Implementation Includes.

16
Renaming a component
In order to generate code, you must first create a
component.
Expand the components in the browser and rename
the existing component called DefaultComponent to
Test. Also name the Directory to Test.

Executable
17
Test component
Now expand Configurations and rename the
DefaultConfig to Release.

18
Initial instance
Select the
Initialization tab,
expand the Default
package, and select
the Display class.
The main will create an
initial instance of the
Display class.

19
Settings
You need to select an
environment so that
Rational Rhapsody
knows how to create
an appropriate
Makefile.
Select the Settings
tab.
Select the appropriate
environment, for
example: Microsoft.
You will learn about the
many other settings later.

20
Renaming the OMD
Expand the Object Model Diagrams in the browser.
Right-click the Object Model Diagram Model1 to
invoke the features dialog.
Rename the diagram from Model1 to Overview.

21
Generating code
You are now ready to generate code.
Save the model.
Select Generate/Make/Run.
Click Yes to the question:

22
Handling errors
If there are errors during the compilation, double-click
the relevant line to find out where the error occurred.

23
Hello World
You should see the following:

Before continuing, make sure you stop the


executable by one of the following methods:
Closing the console window.
Using the Stop Make / Execution button.
Ctrl+Break.
24
Generated files
The generated files are located in the following
directory:

Display class

Main

Executable

Makefile

25
Editing the code
You can edit the generated files
from within Rational Rhapsody.
Select the Display class, right-click,
and select Edit Code.
Both the implementation (.cpp ) and
specification (.h ) are shown in
tabbed windows.

26
Modifying the code
You can modify the generated code.
In the Display.cpp file, change the implementation to
print out Constructed instead of Hello World.
Transfer the focus back to another window to
roundtrip the modifications back into the model.
Note that the model has been updated automatically.

In general, the roundtripping works very well, but


beware not everything can be roundtripped.
27
Displaying the Main and Make
The Main and Makefile can be displayed by simply
double-clicking the hyperlinks:

28
Project files

AutoSave

Generated code

Project workspace

Visual basic macros

The model

29
Extended exercise
You can customize Rational
Rhapsody to get quick access to the
location of the current project.
Select Tools > Customize.

30
Customize
Click to enter a new entry
Explore to the Tools menu.
Set the Command to
explorer.
Set Arguments to .
Click OK.
Select Tools > Explore.

31
Exercise 2: Count down

32
Copying a project
Select File > Save As.
Press to select the work folder.
Press to create a new folder.
Rename New Folder to
CountDown.
Select the new folder CountDown.
Save the project as
CountDown.rpy.
The new CountDown project is
opened in Rational Rhapsody with
the previous workspace
Each time there is an auto-save, Rational
preserved. Rhapsody only saves just what has changed
since the last auto-save.

33
Loading a project
Choose one of the following ways to open a project:
Start Rational Rhapsody and select File > Open.
Or double-click on the file.
Or start Rational Rhapsody and drag the file
into Rational Rhapsody.
Or use Open Project in the Welcome screen.

The Rhapsody.ini file determines which Rational Rhapsody (C / C++ / J / Ada)


will be opened on double-clicking the .rpy file.
34
Adding an attribute
To add an attribute, double-click on the Display class
to bring up the features and select the Attributes tab.
Click New to add an attribute count of type int.
Set the initial value to 0.

35
Generated code for an attribute
Click Save then edit the code for
the Display class so you can examine
the code.

Initial Value

Mutator

Protected attribute
Accessor
36
What are accessors and mutators?
By default, all attribute data members in Rational
Rhapsody are protected.
If other classes need access to these attributes, then
they must use an Accessor, for example, getCount()
or Mutator, for example, setCount().
This allows the designer of a class, the freedom to
change the type of an attribute without having to alert
all users of the class. The designer would just need to
modify the accessor and mutator.
In most cases, attributes do not need accessors or
mutators; you will see later how to stop them being
generated.

37
Attribute visibility
Changing the Visibility in the Attribute features dialog
changes the mutator and accessor visibility (not the
data member visibility).

38
Adding an operation
Using the features for the Display class, select the
Operations tab > Primitive Operation.
Add a new primitive operation called print.

39
Arguments
Double-click Print to open the features for the print
operation.
Select the Arguments tab.
Add an argument n of type int.

40
Adding implementation
Select the Implementation tab for the print operation
and add:

cout << Count = << n << endl;

41
Another print operation
In a similar way, add another operation called print,
this time with an argument s of type char* and with
implementation:
cout << s << endl;

Set the argument type before setting the name.


This avoids a conflict where the two print
operations have identical signatures.

42
Operation isDone()
Add another operation called isDone that returns a
bool and has the following implementation:
return (0==count);

By typing 0==count instead of


count==0, enables the compiler to
detect the common error of where =
is typed instead of ==.

43
Active Code View
Select View > Active Code View.
The active code view is context
sensitive and is automatically updated
as the model is changed. The window
also changes dynamically to show the
generated code for the highlighted
model element.

Note that although leaving the active


code view always open is useful, it
does slow down model manipulation
since the code will get regenerated
anytime any model element gets
modified.
44
Using the print operation
In the Active Code View,
change the code for the
constructor to use the print
operation.
Make sure you have selected
the Implementation.

Change the focus to another window such as the


browser and check that this modification has been
automatically round-tripped.

Save the changes.


Generate / Make / Run.
45
Adding a statechart
You would like to get the Display class to count down
from 10 to 0 in intervals of 200ms.
To do this, you need to give some behavior to the
class. You can do this by adding a statechart.
Right-Click the Display class and select Add New >
Statechart.

46
Draw a simple statechart

Action

Default
transition Trigger

State
Guard

Transition

47
Transitions
Once a transition has been drawn, there are two ways
in which to enter information:
In text format - example: [isDone()]/print(Done);
By the features of the transition (activated by double-
clicking or right-clicking on the transition).

Ctrl+Enter closes
the entry field.

An empty line forces the action


to appear on a new line.

48
Timer mechanism
A timer is provided that can be used within the
statecharts.
tm(200) acts as an event that will be taken 200ms
after the state has been entered.
When entering into the state, the timer will be started.
When exiting from the state, the timer will be stopped.

The timer uses the


OS Tick and only
generates timeouts
that are a multiple
of ticks.

49
Timeouts
If you have a system tick of say 20ms and you ask
for a timeout of 65ms, then the resulting timeout will
actually be between 80ms and 100ms, depending
on when the timeout is started relative to the
system tick. System tick
20ms

80ms Timeout 100ms time

Start timeout End timeout

If precise timeouts are required, then it is recommended you


use a hardware timer in combination with triggered operations.

50
Counting down
Save
Generate / Make / Run

Constructor

Default Transition

Do NOT forget to close this window, before


doing another Generate / Make / Run.

51
Statechart symbol
Now that the Display class is Reactive
A reactive class is one that reacts to receiving events or
timeouts.
Identified by symbol in the browser and the OMD.
Also note that the Statechart appears in the browser.

52
Generated code: display.h
Use the Active Code View to examine the generated
code for the Display class.
Framework class

Framework includes

Thread on
which to wait

Note that the Display class inherits from OMReactive, which is


one of the framework base classes. This is a class that simply
waits for timeouts or events. When it receives a timeout or an
event, it calls the rootState_processEvent() operation.
53
Generated code: display.cpp
Display::Display(IOxfActive* theActiveContext)
The constructor needs to know on which thread to wait.
Display::initStatechart()
Called by the constructor to initialize the attributes used to
manage the Statechart.
Display::startBehavior()
Kicks off the behavior of the Statechart, invokes the
rootState_entDef() via OXF calling
OMReactive::startBehavior().
Typically invoked from outside after construction completed.
Display::rootState_entDef()
Called by OMReactive::startBehavior() to take the initial
default transition.
Display::rootState_processEvent()
Called though OXF operation OMReactive::processEvent()
whenever the object receives an event or timeout.
54
Statechart implementation
Change the statechart implementation
Select the features for the configuration
Release.
Select the Settings tab and set Statechart
Implementation from Flat to Reusable.
Save / Generate / Examine code.

The Rational Rhapsody framework allows two


ways of implementing statecharts:
Reusable is based on the state design pattern where each state is an
object.
Results in faster execution and if a lot of statecharts are inherited,
can result in smaller code.
Flat uses a switch statement.
Results in less code that is easier to read, but is slower.
55
Extended exercise
Experiment with the line shape of transitions.

56
Design level debugging
Up to now, you have generated code and executed it,
hoping that it works. However, as the model gets
more and more complicated you need to validate the
model.
From now on, you are going to validate the model by
doing design level debugging, this is known as
Animation.

57
Animation
Create a configuration by
copying the Release
configuration:
Press Ctrl and drag the
Release configuration onto
the Configurations folder.
Rename the new
configuration Debug.
Set the Instrumentation
Mode to Animation.

58
Multiple configurations
Now that you have more than one configuration, you
must select which one you want to use.
There are two methods:
 Right-click the configuration
and select
Set as Active Configuration.

 Select the configuration


using the pull-down box.

59
Animating
Make sure the active configuration is Debug before
doing Save then Generate / Make / Run.
Run will cause the Animation toolbar to be displayed.

60
Animation Toolbar
Automatically appears when an executable model is run and
instrumentation is set to Animation.
To display or hide during animation session, select View > Toolbars >
Animation.

For detailed button information, select Help > Help Topics


and search on animation toolbar.
For example, grayed out (disabled) Thread button indicates single-
threaded application.

61
Starting the animation
Click the Go Step button.
Note that the Display() constructor appears in the Call
Stack.
Continue to Go Step until the Executable is Idle
message appears in the Animation window.

62
Class Instance
Browser contains an instance of the Display class.
Right-click the instance and select Features.
Note that the attribute count has been initialized to 10.

63
Statechart Instance
Right-click the instance and select Open Instance
Statechart.
Highlighted state indicates the
current state of the model.
If you do not see a highlighted
state, you may be looking at the
statechart of the class (design)
rather than the statechart of the
instance (runtime).
Default transition has also been
triggered.
Started will have been
printed to the display.

64
Go Idle / Go
Click Go Idle to advance to next timeout.
The executed transition chain in statechart is highlighted.
Value for count is
printed to display.
Condition is
checked for
is done.
Not done so value
of count is
decremented.
Click Go and
watch the animation
until the instance is
destroyed.
Exit the animation.
65
Destructor
Add a Destructor to the Display class.

Add implementation print (Destroyed);

Make sure you enter the code


into the Implementation and not
the Description field.

Save then Generate / Make / Run.


66
Sequence diagrams
From the browser, create a new sequence diagram
called execution.
This sequence diagram will be used to capture what
happens in execution.
Operation Mode will be discussed later but for this example,
it does not matter if Analysis or Design is selected.

67
Adding instances
Add a System Border to the sequence diagram.

Drag the Display class from the browser onto the sequence
diagram.

68
Drawing a sequence diagram
Normally, you would describe an actual scenario
similar to this one here, however in this case, you are
more interested in capturing what actually happens.

For the purpose of


this training, you only
need the system
border and the
Display instance line.
There is no need to
add any operations.

69
Animated sequence diagrams
Start the animation and click
Go.

If a sequence diagram is
open, then Rational Rhapsody
creates a new animated
sequence diagram based on
the execution.
Note that the animated sequence
diagram captures operations,
timeouts, and states.

70
Extended exercise I
Rational Rhapsody can
display the return value on
animated sequence
diagrams. To do so, you
must use a macro
OM_RETURN.
In the implementation of the
operation isDone(), replace
return with OM_RETURN.

71
Extended exercise II
Try adding an extra state pausing. Then you will
see the instance changing states.

72
Properties
There are many properties that allow customization of
the tool and the generated code.
Properties can be set once and for all by modifying
the site.prp file in the Rhapsody\7.5\Share\Properties
directory.
The factory.prp and factoryC++.prp files contain all
the Rational Rhapsody properties.

It is recommended you modify the


site.prp or siteC++.prp files rather than
the factory.prp and factoryC++.prp files.
To do so, it is easiest to copy and paste
from these files into the site.prp or
siteC++.prp file.

73
Properties hierarchy

factoryC++.prp factory.prp
SiteC++.prp
project site.prp
profile

component
configuration
If a stereotype is package
applied to an
element, a property class
is assigned to that
stereotype takes operation/attribute/
precedence over the relation/type/
elements property.

74
Project properties
Bring up the Features for the CountDown project and
select the Properties tab.

75
Properties view
There are a very large number of properties which can
be used to customize the tool and the generated code.
In order to facilitate access to these properties, there
are several views that can be applied to the
properties.
For this training course, you use the most common
properties which can be seen using the Common
view.

It is relatively easy to
modify the list of
properties that can be
seen in the Common
view.

76
Properties views
There are several useful views of the Properties:

Properties that have been Only properties that have


overridden for the currently been overridden for the
selected element & any currently selected element
parent overrides

A user defined list of the most


commonly accessed Properties filtered by
properties some keyword

77
Useful property
One useful property is
General:Graphics:MaintainWindowContent.
Setting this property means that if the size of the
window is changed, then the view of the contents
changes proportionally.
Set this property.

Once a property has been


modified it is highlighted. To
restore the default, right-click
on the property and select
Un-override.
Note also the description is
displayed for the selected
property.

78
Overridden properties
Select View Overridden.

This shows just the


properties that have been
modified.

79
General:graphics:MaintainWindowContent
Once this property has been set, changing the size of
a window should keep the same view:

You need to close any open windows and then


reopen them after setting this property.
80
Accessors and mutators
If accessors and mutators
are not needed for
attributes, then properties
can be set to stop their
generation.
Set these two properties
so that ALL attributes in
the project will have
neither an accessor nor a
mutator.

81
Overridden properties
For the attribute count, you want an accessor.
Selecting the overridden filter shows that the
AccessorGenerate and MutatorGenerate properties
have been overridden higher up in the property
hierarchy.
Select the count attribute and override the property:
AccessorGenerate.

82
Locally overridden properties
Select the View Locally Overridden filter to show
that just the AccessorGenerate property has been set
locally.

Generate code and check that there is just an


accessor for the attribute count.

83
Property filter
A customized view of the
properties can be created by
using the Filter view for example:

84
Extended exercise
Experiment with some of the properties such as:
CG:CGGeneral:GeneratedCodeInBrowser
You must regenerate the code after setting this
property.

85
Formatting individual items
Line Colors, Fill Colors, Fonts, etc of
selected element(s) can all be
formatted by right clicking and selecting
Format.

86
Advanced drawing capabilities
These advanced drawing capabilities are common to
most diagrams:
Align items to Make item Give items same
Show rulers spacing size
common edge same size

Snap to grid

Turn grid on/off

Stamp mode -
use when drawing
same items
repeatedly

87
Aligning items to common edge
A pivot selection mechanism is used for aligning,
sizing and spacing:
1. Select by area 2. Select the pivot class by holding Ctrl and selecting

3. Choosing
align left,
aligns all
classes to
the class
(class_4)

88
Site.prp / SiteC++.prp
Adding new environments is done via the file
siteC++.prp.
Each organization or team may want to always set
certain properties for all of their Rational Rhapsody
projects. To do this, set these properties for every
Rational Rhapsody project by putting them into the
file site.prp .
These files can be found in the \Share\Properties
directory.

89
Exercise 3 : Dishwasher

90
Dishwasher
Create a new project Dishwasher; make sure that it is
created in its own folder.

Draw a single class Dishwasher.

91
Attributes
Add the following attributes all of which are of type
int and with initial value of 0.

92
Operations
Add the following operations,
with appropriate return types
and implementations:

Make sure that the setup


operation returns void, and all
the others return bool.
93
Types
In the implementation for the
operation isInNeedOfService(), a
constant called MAX_CYCLES is
used.
Select the Default package, right-
click and select Add New > Type.
Enter MAX_CYCLES as name,
ensure that Kind is set to Language
and add declaration: const int %s=3;

%s is a shortcut
for the name of
the type.

94
Creating a component
As in the previous exercise, rename the
DefaultComponent to Test and the
DefaultConfig to Debug.
Select Animation and create an initial instance of
Dishwasher.

95
Save / Generate / Make
Before adding a statechart, be sure there are no
errors by doing a build.
Save Generate / Make / Run.

96
Creating a statechart
Add a Statechart to
the Dishwasher class.

Draw a single
state as large
as possible
called active.

When drawing a
complex diagram such
as a Statechart, it is
strongly recommended
you maximize the
Statechart window and
close all other
windows.
97
Creating concurrent states
Click And Line to create concurrent states.

This box with


active inside To draw the AND line, either
appears when click and drag the line or
the AND lines click to start the line then
are drawn. double-click to end it.

Draw this line first.

Concurrent
states

98
Displaying state names
Each of the three AND States names can be displayed
by selecting the state and using Display Options to
show the Name.

99
Naming the concurrent states
With the concurrent states names displayed, they can
be changed using the features to running, service, and
mode.

100
Adding nested states
Select the
Stamp mode

then add the


following states:

To change the size


of an outer state,
without changing
the inner states,
press Alt when
changing the size.

101
Adding history and diagram connectors
Add a History connector to the on state.
Add two Diagram connectors both
named done.

102
Adding default transitions
Add Default Transitions:

103
Adding the transitions
Add Transitions and Actions:

When you
need to type a
name of an
existing
operation or
attribute, you
can use
Ctrl+ Space to
facilitate
entering these
names.

104
Action on entry
In the normal state, add an Action on entry to set
cycles=0;.
Click to display the action.

Once an action has been set, the


symbol is shown.

105
Save / Generate / Make / Run
Save / Generate / Make / Run.
Click Go idle to create a Dishwasher instance.

If there is no instance created, then it is


probable that an initial instance of Dishwasher
was not selected in the configuration.

106
Animated statechart
Check that there are three concurrent animated states:

3
2

107
Injecting events
The Dishwasher is in an idle state waiting for some
events.
Generate the event evStart by right-clicking
anywhere in the animated statechart and selecting
Generate Event
The event evStart should appear in the event queue.

Events can also be


generated via the
Command prompt
or via the Event
Generator.

108
Design level debugging
Click Go and watch the animation.
Does your Dishwasher work as expected?
What happens if you open the door when it is on,
does it remember what state it was in?
Why does the Dishwasher become faulty after four
cycles?
Can you get the Dishwasher back to the normal
state?

109
Intense / quick
Modify the setup operation so that the timings are
different in the quick and intense modes.
Use the IS_IN macro to test if the object is in a
particular state.

Save / Generate / Make / Run.


It should now be quicker to get the Dishwasher into
the faulty state. 110
Extended exercise 1
Using the IS_IN macro and a guard, prevent the
Dishwasher from being started if it is faulty.

111
Extended exercise 2
The setup() operation has
conditional behavior.
Add a flowchart to visualize
its logic.

A Flowchart is a specialization of a UML


Activity Diagram. If a Flowchart is present, it
defines the implementation for an operation
and the contents of the implementation tab
are ignored by the code generator.
112
Breakpoints
Setting breakpoints can be done in a similar way to
injecting events.
Simply right-click on the animated state where you
would like to break, choose Add Breakpoint and
click OK. Breakpoints can be
added/removed via the
breakpoint icon
on the animation toolbar.

113
Using the simulated time model
At the moment, System tick is used for all the
timeouts and so a timeout of 1000ms takes 1000ms,
which means that all simulations can be long.
There is an alternative time model that may be used,
that is the Simulated time model. With the Simulated
time model, all the timeouts are executed in the
appropriate order. But rather than waiting, the
shortest timeout immediately times out. This means
models can be tested much quicker.
Make a copy of the Debug configuration, rename it to
Sim, and set the Time Model to Simulated.

114
Command prompt
Events and breakpoints can also be generated
through the command prompt.
For example, you could inject the evStart by typing
Dishwasher->GEN(evStart) in the command
window.
Using the command window to invoke scripts is very
useful.

GEN is a macro that creates


the event before sending it to
the object. GEN(evStart)
send(new evStart, ).

115
Panel diagram
One way of testing the Dishwasher is to use a panel.
Add a Panel Diagram called Dishwasher Panel.

Panel Diagrams can


only be used with
animation
configurations.

116
Panel diagram
Add LEDs, push buttons, level indicators, and a digital
display to the panel.

117
Renaming panel elements
Double-click the text of each LED and the digital
display, renaming the panel elements as shown:

118
Level indicators
For each level indicator:
 Use the Display Options to select None.
 Use Features to set the Maximum value to 5.

119
Push buttons
For each push button:
 Use the Control Display Options to select None.
 Use the Features to set the Caption appropriately:

120
Box
Draw a box around the panel.
Right-click and select Send to Back.
Right-click and select Format to
change the fill color.
Add text Rational Rhapsody
Dishwasher Panel, with desired
font and size.

121
Bind
Double-click on each panel element and bind them to
the appropriate event, attribute, or state:

122
Panel
There is no need to generate or make, just Run
Use the panel to drive the dishwasher.

When using the panel, you should use the Debug


configuration.
123
Extended exercise 3 - Creating a test script
Another way of testing Dishwasher is by running a
script.
The script can be created in the following way:
In the Test Component, select Add New File.
Name the file TestScript.cfg.

124
TestScript.cfg
Set the Path to ..\..
Set the File Type to Other

The script you are about


to create is contained
inside the model and is
generated every time
that code is generated.

125
Script contents
Select the Elements tab.
Add a New Text Element.
Enter Script Contents as the name.
Click to start the text editor.

126
Script
Enter the following:

Remember - you can use the cheat


sheet.

This script logs everything that


happens including timing information
to a file called TestScript.log
For more information on the scripting
language, search for example
timestamp in the user reference
manual.

Do not leave any blank lines or any


leading spaces.
Note also that there is no
roundtripping of this file.

127
Running the script
Save / Generate / Make / Run.
Use the command prompt to run the script.

Once the script has run and terminated, stop the


animation.
The script should have created a file called
TestScript.log. This file can be edited by adding
another file called TestScript.log of type Other and
Path ..\.. .
If the script is called OMAnimator.cfg, it
automatically runs when the animation is
started. This script must be located in the
project directory.
128
Reading TestScript.log
Select the TestScript.log file in
the browser, right-click and select
Edit File
Elapsed Time

129
Events and receptions
For each event that was added to
the statechart, the class has a
Reception, whereas the event Receptions

itself is declared in the package so


that it can be reused by other
classes.
Each event is a class that inherits
from the framework base class
OMEvent.

Events

130
Extended exercise 4
Create a sequence diagram and see how often
the operation isInNeedOfService() is called.
Basically, isInNeedOfService() gets called every
time there is a change in the model.
This could cause considerable overhead and it
may make sense to replace the guard by an event
evFault.
Replace the guard with event evFault. Modify the
statechart so that when cycles gets changed, you
can check to see if service is needed. If service is
needed, generate evFault. This can be done using
GEN(evFault);

131
Exercise 4: Dishwasher system

132
Make default
Rename the Object Model
Diagram Model1 to Dishwasher
System Overview.
Resize the Dishwasher class so
that it is as shown:

To set the default size of any


classes that get drawn, select the
Dishwasher class, right-click, and
select Make Default
Select New Element Size and
Project.
You could use Save As to
change the name of the project
to DishwasherSystem.

133
Aggregation and association
Add two new classes Motor and
FrontPanel to the Dishwasher.
Draw an aggregation from the
Dishwasher to the Motor and a directed
association from the FrontPanel to
the Dishwasher. Directed Association

Aggregation

134
Directed aggregation
The Motor does not need to know
about the Dishwasher.
Using the features, change the
association so that it consists of only
End itsMotor.

135
Role names
Using the Display Options, display the role names
(Name) for both associations.

The role name, for example, itsMotor is the name by


which the Dishwasher knows the Motor. This name
appears in the generated code. The association name
however is rarely used and for association itsMotor,
might be set to something such as switches or
controls.
136
Motor class
Add two operations on() and off() to the Motor class.
There is no need to add an implementation.

137
itsMotor
Select the Active Code View and click on the
association itsMotor to see the generated code.

138
itsMotor->on() itsMotor->off()
Notice that itsMotor is a pointer to a
Motor class.
This means that if the Dishwasher
wants to call a public operation of
the Motor class, such as the
operation on(), then it can do so by
dereferencing this pointer for example:
itsMotor->on();
itsMotor->off();
Modify the Dishwasher so that when it
enters the on state, it calls itsMotor-
>on() and when it exits the on state, it
calls itsMotor->off().
State on
139
FrontPanel
Imagine there is an interrupt that occurs every time a
key gets pressed on the FrontPanel. This interrupt
routine could read the keys and then send an event
to the FrontPanel passing an argument indicating
which key has been pressed.
Add the following statechart to the FrontPanel class:

140
evKeyPress
In order to be able to send an argument with the
event evKeyPress, it needs to be added to the event
via the browser.
Add to evKeyPress, an argument key of type int.

If an event has an argument, then Rational Rhapsody


provides a pointer called params that can be used on
the transition where the event occurs, to get access to
the argument. 141
Operation processKey
Add a private operation processKey to the
FrontPanel class.
Add an argument aKey of
type int and implementation.

GEN is a macro that can be


used to send an event to another object.
itsDishwasher->GEN(evStart) is the same as
itsDishwasher->send(new evStart()).
send is an operation of the base class OMReactive (this
is discussed later).
142
Instances
You now need to create instances of the classes.
There are several options in which to do this:
1. Create initial instances of all the classes.
2. Create global instances of all the classes.
3. Create an initial instance of just the Dishwasher and
then get it to create the other instances.
4. Use an additional class to create the instances.

No matter which solution is taken,


you must ensure that the relations
get initialized. If this is not done,
the relations will be NULL pointers
and the generated executable will
crash.

143
Option 1: Initial instances
Create initial instances of all the classes. The
relations must be initialized manually.

get and set


operations are
generated for each
relation.
144
Option 2: Global instances
Create global instances Objects
of all the classes.
In order to initialize the
relations, links must be
added between the
instances. Links

This solution works, the


only problem is that
these objects are global.

145
Option 3: Composition
You can use the Composition instead of the
association and aggregation. Then, create an initial
instance of the Dishwasher.
This solution works fine, but the relation between
the FrontPanel and the Dishwasher is now bi-
directional.

146
Option 4: structured class
The best solution is to use another class that has the
responsibility to create all the instances and to
initialize the relations.

Structured class

Links

Objects

147
DishwasherBuilder
Implement Option 4.
In the browser, add a class called DishwasherBuilder.
Add a Structure Diagram to the class called
DishwasherBuilder Structure.
Right-click the class then Add New
> Diagrams > Structure Diagram.

148
Structure diagram
Drag the three classes from the browser into this
structured class.
Note that the classes appear with the Default size
that was specified.

A Structured Class is
sometimes called a
Composite Class.

149
Objects / parts
Select all these classes, then select Make an Object
to turn them all into Objects. An object inside a class
is called a part.

A part becomes an object when


its parent becomes an object.

150
Links
The relations must be initialized.
This can be done graphically by
using a link.
Draw the two links between the
objects.

151
Component
An initial instance of the DishwasherBuilder must be
created. The DishwasherBuilder then creates all the
objects and initializes the relations between them.
Modify the Sim configuration of the Test component.

Derived

Derived means:
generate code for just
the classes that are
necessary based on
the initial instances.

152
Checking that the relations are initialized
Save Generate / Make / Run.
Check that all the instances are created and that all
the relations are initialized.

153
Pressing a key
Check that everything works
correctly by creating a
sequence diagram and
sending event
evKeyPress(0) to the
FrontPanel.

154
Generating a Web page
Another way to test the model,
is to generate a Web page.
Simply add the stereotype
Web Managed to each
attribute / operation / event
that you want to control /
visualize from the Web page.
Then, select Web Enabling in
configuration.

To visualize / modify an
attribute, you must enable
the accessor / mutator for
the attribute.

155
Web Managed
Set the stereotype Web Managed for all the
attributes in the Dishwasher class as well as all the
events in the Default package. Also set the same
stereotype for the setup() operation.
Select Web Enabling in the configuration.

156
Hyperlink
To facilitate direct access to the
generated Web page, a hyperlink
can be added at the project level
that points to the Web page.
Add a hyperlink pointing to:
http://localhost/

157
http://localhost/
Save Generate / Make / Run.
Run continuously.
Double-click the hyperlink to
see the Web page.

Unlike Panel Diagrams, Webify


works with or without animation.
158
Turning the motor into an interface class
Return to the Object Model
Diagram showing the Motor
class.
Edit the Motor features to add
the Interface stereotype to
the Motor class.
Check the abstract box for
the on() and off() operations
of Motor.
Generate code and examine
Motor.h noticing the pure
virtual declaration of the on()
and off() operations.

159
Realizing the motor
On the same OMD, add two classes AC and DC.
Add realizations to the Interface
class Motor.

160
Realize the base class
Right click the AC class and select
Realize Base Classes.
A dialog box opens to allow you to
implement the abstract operations
and optionally implement the
virtual operations.

The Implement Base


Classes feature can be
invoked automatically by
selecting this box.

161
Implement Base Class
Select the off() operation
indicating the need to
implement it.

Edit Code is now


available and can
invoke the editor.

For the AC Motor


operations, add the
operation bodies as
shown.

162
Using the derived class
Now that Motor is abstract, it
cannot be instantiated, so the
AC class is used instead.
Highlight the Motor part in the
DishwasherBuilder composite class
and select Delete from Model.

Drag the AC class into the


composite class from the browser
and select Make an Object.

163
Add link to derived class
Since the Motor class
was deleted and AC
was added, you must
create a link to AC
from the Dishwasher
part as shown.
Examine what
association is used in
the new link, notice
that it is itsMotor from
the base class.

164
Running with the AC motor
After a Generate/Make/Run and the injection of an
evKeyPress(0) to the FrontPanel, check to see the
following output:

No code changes have been made in the


Dishwasher, but it is now using AC as its motor.

165
Extended exercise 1 AC or DC

Modify the model so that either a DC Dishwasher


or an AC Dishwasher may be created.

166
Summary
You should now should be able to do the following:
Create a new project.
Do some basic modeling using classes, attributes,
operations, relations and state charts.
Generate and compile code.
Set Properties to customize the tool and the generated
code.
Edit the code and roundtrip the changes back into the
model.
Debug the model by injecting events, setting
breakpoints, capturing behavior on sequence diagrams,
and visualizing the state of objects.

167
Page left intentionally blank

168

IBM Software Group

Essentials of IBM Rational Rhapsody v7.5 for Software


Engineers (C++)
Case Study

2009 IBM Corporation


Objectives
Now that you understand the basics of Rational
Rhapsody, you can create a small project starting
with some requirements and gradually implement
the project proceeding use case by use case.
During this project, you will learn how to:
Use profiles
Manage requirements
Capture scenarios using sequence diagrams
Use ports to create reusable components
Manage one to many relations
Create threads

2
Case study: Cash register

3
Cash register requirements 1
A small stand-alone cash register needs to be
designed that reads barcodes of products that a
customer has selected.
When a product has been identified, its name and
price are displayed on a display.
If the barcode cannot be read automatically, the
message "Unknown product" is displayed and the
barcode can be entered via the cashiers keyboard.
When all the selected products have been read, a
ticket is generated containing the list of all the
selected products with the unit price, quantity, and
total price.

4
Cash register requirements 2
Some products can be on special offer. It should be
possible to add special offers such as "Buy one get
one free", "10% off ", or "Buy 3 for 1 Euro".
Products can be cancelled one at a time.
A keyboard allows the cashier to start a session,
cancel the last selected product, end a session, and
issue a ticket.
It must be possible to be able to change hardware
platforms in the future.
The cash register will contain a local database of
products.

5
Before you start 1
Before starting this example, spend some time to
trying to come up with some use cases and actors.

Group Exercise!

6
Before you start 2
Spend some time trying to find some classes and
draw an Object Model Diagram showing how these
classes are connected.

Group Exercise!

7
Before you start 3
During this case study, there will be times where
you need to enter several non-trivial descriptions
and operation implementations.
There are several places where it is necessary to
type several lines of code. For those of you who
do not like typing, a cheat sheet is available
to allow text to be cut and pasted. During the
exercises, look for the symbol indicating that text
can be cut and pasted from the cheat sheet.
In order to optimize the allocated classroom time, it
is not necessary to enter descriptions, but in a real
project it is very important to enter them. If no
descriptions are entered, then the final
documentation will be a lot less useful.
8
Profiles
Once you have started to use Rational Rhapsody
for a while, you will start to find that there are
certain properties that you always want to have set.
You will also find that you want to be able to create
your own stereotypes, add your own tags, and so
on.
All these properties, stereotypes, and tags can be
grouped into a profile that can be used in one or
more projects.
For the Cash Register exercise, you will be using a
profile that will be provided by the instructor.

9
CppProfile

10
Using the profile
Copy the profile so that it is located in \Share\Profiles
directory

When you create a project, you can create one based


on this profile.

11
Cash register
Create a new project called CashRegister in C:\Work
and select Project Type is CppProfile.

12
Referenced profile
The model now contains a read-only
reference to the CppProfile.
Take a look at the profile and observe the properties
that have been overridden and the stereotypes that
have been added.
Note for instance that all diagrams now have a frame.

13
Project description
You could start by adding a simple description to the
project.
When you generate a report on the model, all descriptions
that are entered, like this one, can appear in the final
documentation.

14
Requirements Document
The requirements are in a document titled
Cash_Register_Requirements.doc.
Requirements are identified using a specific Word style.

15
RequirementsPkg
You will add this requirements document to the
model. Before you do this, rename the existing
package Default to RequirementsPkg.

16
Controlled file
You can add this Word document to the model as a
controlled file. This means that the file is now
contained inside the model.
Right-click RequirementsPkg and select the Word
document as a Controlled File.
The document will be copied to the _rpy directory.

17
Capturing requirements
Since you have some requirements in a document, you can
start by importing these through the Rational Rhapsody
Gateway.
Right-click CashRegister to invoke the Rational Rhapsody Gateway.

If you do not have the


Rational Rhapsody
Gateway, then you could
either manually add the
requirements or simply
skip this section.

18
Rational Rhapsody Gateway
The initial Rational Rhapsody Gateway screen
shows the current elements.

19
Rational Rhapsody Gateway configuration
Select Edit Project to open the configuration
editor.

20
Choosing Word
Drag the Word document (from
the CashRegister_rpy directory)
into this view.
Add a cover from the UML
Model to the Word document.

This indicates that the


UML Model covers the
Word document (and
also covers itself, in case
you add any derived
requirements).

21
Analyzing the project
Click OK and then Yes to analyze the Word
document.

22
Showing Word requirements in Rational Rhapsody Gateway

In the Rational Rhapsody Gateway main view, you can


see that the Rational Rhapsody Gateway has
extracted the requirements from the Word document.
You can also see
that the coverage
is 0% because
the requirements
are not yet linked
to any Rational
Rhapsody design
elements.

23
Word coverage analysis
You can see that the text of the Requirement also
appears in the Rational Rhapsody Gateway when you
click on the Coverage Analysis View tab and then
click on a requirement.

24
Adding requirements
Next, highlight UML Model Rhapsody and select
Tools > Add high level requirements
If you forgot to select UML Model Rhapsody, the Add high
level requirements will be grayed out.

Select RequirementsPkg then


click OK.
25
Adding requirements
This should add nine requirements to your model.

Click OK.

Click Yes to reload the Rational Rhapsody model.

26
Requirements in Rational Rhapsody
Close the Rational
Rhapsody Gateway.
In Rational Rhapsody, you
can now see the imported
requirements.

Later on, you will


connect these
requirements to the
elements of the model
that implement them.
27
AnalysisPkg
Add a new package called AnalysisPkg.

Add a new use case diagram


called Principal Uses to the
AnalysisPkg.

28
Principal uses
Draw the following Use Case Diagram.

29
Extended exercise
Sometimes it makes more sense to
represent an actor with a bitmap
rather than a stick figure.
Add the Cashier.jpg as a controlled file to
the AnalysisPkg.

30
Associate image
Select Associate Image to associate this .jpg to the
Cashier actor.

31
Actors
Whenever you add new elements to the
model, you should add descriptions.
For example, you could
add descriptions for the actors.

32
Sum the cost of selected products
You can add a description to the principal use
case Sum the cost of selected products.

33
Configure the products
You can also add a description to the other use case
Configure the products.

34
Secondary use cases
Add another use case diagram entitled Secondary
Uses.
Drag the Sum the cost of selected products use case
onto this diagram. Then, add the new use cases and
dependencies.

Dependency

Double-click each
dependency and set the
stereotype include.

35
Browser
The browser should
now look like this:

36
Keep count of selected products
For the secondary use case Keep count of
selected products, you could add the
following description:

37
Generate a ticket showing total cost
For the secondary use case Generate a
ticket showing total cost, you could add the
following description:

38
Manage special offers
For the secondary use case Manage
special offers, you could add the following
description:

39
Navigation
In order to navigate
within the model, you
can add internal
hyperlinks for each
model element.
For example, it would
be useful to be able to
navigate from the
Principal Uses
diagram to the
Secondary Uses
diagram.
Add the following
hyperlink.

40
Hyperlink
Set the hyperlink to point to the Secondary Uses
diagram.

41
Following the hyperlinks
You can now navigate between the use case
diagrams by following this hyperlink:

You can add as


many hyperlinks
as you want to
each model
element.
42
Use case driven approach
Approach this problem one use case at a time.
Complete the use cases in this order:
1.Configure the products.
2.Keep count of selected products.
3.Generate a ticket showing total cost.
4.Manage special offers.

When doing this case study, you should progress at your


own speed and in the allocated time should be able to
complete at least the first two use cases. The last two use
cases are really extended exercises if you have time.

43
Use case 1

Configure the
products

44
Which architecture?
As well as implementing the first use case Configure
the products, you also want to put together an
architecture that works for all the use cases.
There are many different architectures that could be
used, for example you could have a simple
architecture such as:

This design works, but


there is high coupling
between the classes,
making reuse difficult.
For example, if you want
to reuse the keyboard, it
would be difficult since it
depends on the
CashRegister class.
45
Hardware independent
Requirement REQ8 indicates that you must design
the CashRegister, so that hardware platforms can be
changed in the future.

46
Using interface classes
If you change the hardware platform, then it is
likely you will have to change the implementation
for the Printer, Display, Keyboard, and
BarcodeReader classes.
To make it easier to change these classes in the
future, you could introduce some interface
classes:

This design now means


that the classes that
risk changing have
been isolated from the
classes that will not
change.

47
Ports
The previous diagram is the solution that is best
when using UML1.X, however with UML 2, you can
improve this architecture by adding a port to the
CashRegister class: Required Interface

This design now means


that you can easily
connect the CashRegister
to any Hardware as long
as it provides a matching
port.

Provided Interface

48
CashRegisterPkg
Add a new package called CashRegisterPkg.
Move the OMD Model1 to this package and rename
Cash Register Overview.

To move the OMD, click and


drag it onto the
CashRegisterPkg package.
49
Packages
Add a new OMD called Domains Overview.
Drag the AnalysisPkg package onto the OMD.
Resize and then select Make Default.

50
Package architecture
Drag the other packages onto the OMD, add two
more packages, HardwarePkg and InterfacesPkg,
then add the dependencies.
If the package already exists, then you can use Crtl+Space
to select a name of a package.

51
Domain overview
The previous diagram indicates that there are no
dependencies between HardwarePkg and
CashRegisterPkg.
Classes inside these two packages only
communicate via classes inside the InterfacesPkg.
This means that you can easily replace the
HardwarePkg by another hardware package in the
future without having to modify the
CashRegisterPkg.

52
InterfacesPkg
The interfaces package contains all our interface
classes that will be used by the CashRegisterPkg
and the HardwarePkg.
Add the following Interfaces to the InterfacesPkg:

53
CashRegister overview
On the CashRegister Overview diagram, draw the
CashRegister class.
Click to convert the view from Specification to
Structure.

Specification view Structured view

54
Adding ports
Add a port hw to the CashRegister structure as
shown.

55
Port contracts
Set the following contracts for the port:

56
CashRegister description
You can add a description for the
CashRegister class.

57
Product database overview
Add a new OMD in the CashRegisterPkg called
ProductDatabase Overview.
Drag the CashRegister class from the browser onto
this diagram.
You can select to hide or show ports via the Ports dialog.

58
ProductDatabase
Add the classes Product and ProductDatabase.
Draw the relations between the classes.
Set Multiplicity appropriately.
Composition

Directed association
Multiplicity
*

Aggregation

Specification view

59
Directed associations
Change the aggregation and composition to be
directed.

60
Product attributes
Add attributes to the Product class.
Select Constant for only the attribute name.

61
Product constructor
Add a constructor with following arguments:
Add Initializer.

62
Implicit constructor
By default, Rational Rhapsody generates an implicit
constructor for all classes. To prevent this, set the
following property for the Product class:

63
Generated code
Using the Active Code View select the relation
between the ProductDatabase and the Product
class.

64
OMCollection<Concept>
When the multiplicity for a relation is * (many),
Rational Rhapsody generates an unbounded
collection using the template class
OMCollection<Product*>.
This is similar to a bag. You can put many products in
it and also take them out.
Advantages:
Fast access to a particular element.
Adding elements is fast, since memory pre-allocated.
Safe, will dynamically allocate more memory if needed.
Disadvantages:
The order is not specified.
By default pre-allocates 20 pointers. (Default can be changed.)
Uses templates, which some compilers handle inefficiently.
65
OMCollection<Product*>

66
Ordered relation
Select the Ordered property for the relation.

Instead of setting
this property, you
could have applied
the stereotype
Ordered that is
in the profile.

67
OMList<Concept>
When the multiplicity for a relation is * (many) and the
property Ordered is True, then Rational Rhapsody
generates a linked list using the template class
OMList<Product*>.
Advantages:
Efficient use of memory.
Order is specified.
Safe, will dynamically allocate more memory if needed.
Disadvantages:
Access to a particular element is slow.
Adding elements is slow since memory must be allocated.
Uses templates, which some compilers handle inefficiently.

68
OMList<Product*>

69
Qualified association
A responsibility of the ProductDatabase class is to
allow other classes to find a product given a barcode.
It is possible that you may have 1000s of products
and you will want to be able to lookup a product as
quickly as possible.
To do this, qualify the relation using the attribute
barcode.

70
OMMap<Key,Concept>
When the multiplicity for a relation is * (many) and
the relation is qualified with a key, a map is
generated using the template class
OMMap<key,Product*>.
Advantages:
Lookup of an element using the key is fast.
Efficient use of memory.
Order is specified according to the value of the key.
Safe, will dynamically allocate more memory if needed.
Disadvantages:
Adding elements is slow since memory must be allocated
and the map rebalanced.
Uses templates, which some compilers handle inefficiently.
It is not necessary to set the ordered property;
this has no effect on a qualified association.
71
OMMap<Product*>

This is a balanced tree,


so searching is as fast
as possible.
72
Generated operations
When you look at the code, a lot of useful operations
have been generated. However, you do not need all
these operations, only the following two:

73
Generated operations
You can set properties to tell Rational Rhapsody not
to generate the other operations. However, there is a
stereotype in the profile that we can apply to do this.
Apply the stereotype SimplifiedAccess.

You can use these two operations to add products to


the map and to get a product given a specific
barcode. 74
Creating products
Create a constructor for ProductDatabase
that does the following:

75
Tester
In order to try this, first create some tester Hardware
to connect to the Cash Register.
Inside the HardwarePkg, add a new nested package
called TesterPkg with the following OMD entitled
Tester Overview.
Add a class Tester.

76
Tester port
You need to add a port to the Tester class
that has exactly the opposite contracts to
the port on the CashRegister class.
The simplest way to achieve this is to go
to the browser and find the hw port of the
CashRegister. Then, press Ctrl and drag
it to the Tester class in the browser.
Set the port to be Reversed.

77
Tester builder
Add a class
TesterBuilder.
Add a structure
diagram to the
TesterBuilder class.
Now drag the Tester
class from the browser
onto the TesterBuilder
Structure diagram.

78
Make default
You want to show what
instances will be created by
the TesterBuilder and also
what relations / ports will be
connected. You do not need
to see the attributes /
operations of these classes.
However, by default, Rational
Rhapsody shows the class
with the attributes and
operations fields.
Change the size of the Tester
class to be as shown and
then select Make Default
Select New Element Size
and Project.
79
Tester builder
Remove the Tester class from the view and then
drag both the CashRegister and the Tester classes
from the browser into the TesterBuilder class on the
Structure diagram.

Notice that the


classes should now
appear with the new
default size.

80
Make objects
Select both the Tester and the CashRegister classes
and then select Make an Object.

81
Linking ports
Connect the ports with a link.

Link

82
Component
Rename the existing component to TesterPrototype.
Select the scope as follows:

The scope means the


packages that you want to
generate code for.

83
Configuration
Rename the existing configuration to Debug.
Create an initial instance of TesterBuilder.
Deselect Generate Code For Actors.
Select Animation.

84
Save / Generate / Make / Run
Save then Generate / Make / Run

Ignore the warnings


during the code
generation; you will deal
with those later.

85
Instances
Click Go Idle to create the objects.
Switch from Entire Model View to Animation View.

Check that you


have the same
instances.

86
Initialized objects
Check that each object is
initialized correctly.

87
Use case 2

Keep track of
selected products

88
Scenarios
For this use case there are several scenarios which
need to be drawn in order to help understand how the
Cash Register works. These scenarios will be
described using sequence diagrams:
1. Selecting products
2. Cancelling products
3. Manually entering a barcode

89
Scenario: Selecting products
In the CashRegisterPkg, create an Analysis
sequence diagram entitled Scenario selecting
products.
Drag the CashRegister and Tester classes onto the
diagram.

90
Starting the scenario
Add a condition mark called idle and two
partition lines with associated text.

91
Adding a message
Draw a message evStart diagonally
from the Tester to the CashRegister.

Make sure that the arrowhead of the


evStart message is an open arrowhead
and not a closed arrowhead.

92
Adding more messages
Add messages startSession() and show().
Add a condition mark active.

Make sure that the


show message is
drawn horizontally and
has a closed
arrowhead.

93
Adding more operations
Add an interaction operator.

Select the type to be loop.


Set the condition to be
until all products scanned.

94
Interaction occurrence
Add an interaction occurrence.
Name the occurrence Scan a product.

95
Finishing the scenario
Complete the scenario by adding four more
messages and a condition mark.

96
Reference sequence diagram
Right-click the interaction occurrence Scan a product
and select Create Reference Sequence Diagram.

97
Scan a product
Drag class ProductDatabase onto the Sequence
Diagram.
Add messages as shown.

Ensure that the message evBarcode


is drawn diagonally and has a open
arrowhead.
98
Interaction operand separator
Add an Interaction Operator and an
Interaction Operand Separator.

99
Alt
Select alt from the Type list.
Set Constraints to be [aProduct == NULL] and
[else].
Add three messages:

100
Analysis sequence diagram
Since you used an analysis sequence diagram, none
of the messages that were drawn have been realized,
so they do not yet exist in the browser.
Once you are happy that the scenario is correct, you
can select the un-realized messages and realize them.
When you do this, any message that you have drawn
diagonally becomes an event and any message drawn
horizontally or drawn to itself becomes a primitive
operation.
Before you proceed, check that the three messages
evStart, evBarcode and evEnd are the only messages
drawn diagonally.
If you had selected a Design sequence diagram, then
as each message is drawn, it appears in the browser.
101
Realizing the messages
For each sequence diagram:
Select Edit > Select > Select Un-Realized
Then, select Edit > Auto Realize

102
Browser
Check that the messages
have been realized and
appear in the browser.

103
Operation show()
The show() operation is shown as
being invoked on the Tester
class. In fact, it is being invoked
on the IDisplay Interface class.
Add an argument aMsg of type
char* to the Tester show()
operation and then copy it to the
Interface class IDisplay. Press
Ctrl while dragging it.

104
Operation addProduct()
Add argument aProduct to the operation
addProduct(). Select Product from the Type field
and In from the Direction field.

Note that the browser


indicates that aProduct is
of type Product.
105
Show implementation arguments
You can see that the
Product is passed as a
pointer.
You should set the
browser options so that
this information is also
indicated in the
browser:

106
In / Out / InOut
By setting the direction In, Out or InOut on an
argument, you can control how you pass the
arguments. In the profile that you are using, In, Out
and InOut have been set as follows:

107
evBarcode
In the browser, select the event evBarcode and add
an argument aCode of type int.
Since the Tester is sending this event to the
CashRegister, you need to add the event reception to
the Interface class IBarcodeReader.

108
identifyProduct()
Add argument aCode of type int to the operation
identifyProduct() in the CashRegister class.

109
getProduct()
Add an argument aCode of type int
to the operation getProduct() in the
ProductDatabase class.
Set the return type to be of type Product.

110
Browser
Now that the scenario is complete, you have
populated the browser, which should look like the
following.

111
Scenario cancelling products
Add another
Analysis
sequence
diagram entitled:
Scenario
cancelling
products.
Realize all the
messages.

112
Browser
This scenario should have
added just one more event
evCancel, as well as two
additional operations
removeLastProduct() and
isNoMoreProducts() to the
browser.

Make sure that evCancel is an


event reception.

113
CashRegister statechart
From the scenarios, you
have seen that the
CashRegister receives
events. You also added
a couple of condition
marks indicating states.
Now, you need to add a
Statechart to the
CashRegister.
Add the following
statechart. Note that
since the events already
exist, you can right-click
and select them from the
list.
114
Completing the statechart
Complete the
statechart:

Remember that params


is a Rational Rhapsody
generated pointer that
allows access to the
arguments of the event.

115
Ordered relation
Since you need to be able to remove the last product
added, the order of the products is important.
Therefore, you need to make the relation ordered.
For the relation itsProduct, set the stereotype
Ordered.

You could just have set the property ordered, but by adding a
stereotype you have a visible indication that this is an ordered
relation (and of course the property gets set for you).
116
CashRegister addProduct()
Add the implementation to the addProduct()
operation of the CashRegister class.

OUT_PORT is a Rational Rhapsody macro that allows a message


to be sent via a port. There is no need to know what is connected to
the port.

117
Accessor getName()
In the previous implementation, you called the
accessor getName() for the Product.
With the profile, accessors and mutators are not
generated by default, so you need to tell Rational
Rhapsody to generate an accessor for the attribute
name in the Product class.
Later on, you will use accessors for all the attributes
in the Product class. The simplest way to do this is to
enable accessors for all attributes in the class
Product as follows:

118
Include Stdio.h
Since you have used sprintf, you need to include
stdio.h in the CashRegister class.
In the previous exercises, you did this by setting the
property CPP_CG::Class::ImpIncludes. This
approach works, but there is a better visual way to
do this.
Now, add to this model, a package from another
model that contains the classes that you are
interested in, for example, stdio.
It is added as a reference. In a similar way, you could
reverse engineer the
header files from any
external code that you
need to use. Then, add
them as a reference to
your project.

119
Add to model
Add to model as a reference the
package CppLibrary from the model
RiCpp_Libraries

The instructor will


provide this model.
120
Include Stdio.h
Now that you added the stdio class into the model,
you can start to use it. Note that it has the External
stereotype indicating that you do not want to generate
code for this class.
Drag the stdio class onto the CashRegister Overview
diagram and add a dependency with stereotype
Usage.

121
Scope
Unless the package CppLibrary is in the component
scope, the dependency that you have just added
does not generate the required #include <stdio.h>.
Set the scope for the TesterPrototype component to
include the package CppLibrary.

122
endSession()
Add the implementation for the endSession()
operation of the CashRegister class.

clearItsProduct() is an
operation that gets
generated automatically
and clears (or empties)
the linked list.
123
identifyProduct
Add the implementation for the
IdentifyProduct() operation of the
CashRegister class.

124
isNoMoreProducts()
Ensure that the isNoMoreProducts()
operation returns an int and make it
inline and constant.

Add the implementation.


125
removeLastProduct()
Add the implementation for the
removeLastProduct() operation.

126
startSession()
Add the implementation for the startSession()
operation.

127
getProduct()
Add the implementation for the getProduct()
operation in the ProductDatabase class.
Verify that it returns Product.

128
Save / Generate / Make / Run
Close all diagrams (especially the
sequence diagrams).
Save Generate / Make / Run.
Go Idle.

129
Capturing behavior
You can capture what happens by opening an
animated sequence diagram based on one of our
scenarios, and then inject events.
However, since there is no system border on the
sequence diagrams, you will not see these events.
Create a new sequence diagram Behavior as
shown:

130
Running a scenario
Ensure that the sequence diagram Behavior is
closed, then open an animation sequence diagram
based on Behavior.

131
Injecting events
Go (F4)
Inject the following
events to the
CashRegister instance:
evStart
evBarcode(12345)
evBarcode(12346)
evCancel
evEnd

132
Where is the show?
The resulting sequence diagram looks correct, except
that you do not see any show operations going to the
Tester. That is because the hw port of the Tester is not
behavioral.
Observe that the Rational Rhapsody implementation of ports
is safe. You can safely call the OUT_PORT macro even if
there is nothing connected to the port.
There was a warning about this during the code
generation.

133
Behavior attribute
You need to add some behavior to the Tester class
so that it does something when the show operation
is invoked via the port.
In Rational Rhapsody, the Behavior attribute on a Port
implies that messages (operations or events) specified in
the Ports contract are implemented (or handled by) the
instance containing the behavior Port.
Counter to the notation of behavior is the concept of
delegation where messages will be forwarded to, and
managed by, other Ports.

134
Adding some behavior
Open the features for the
hw port of the Tester class
and check Behavior.

Click Yes to the following


message:

135
Tester show() operation
Add implementation
to the show()
operation.
Because you used
cout, you must do an
include of <iostream>
to the Tester class.
Add a Usage
dependency to the
iostream class.

136
Save / Generate / Make / Run
Save.
Generate / Make / Run.
Re-inject the same events as
before.
This time you should see the
following:

137
Automating the tests
You can check that the model is correct by manually
injecting events and observing the animated
diagrams.
Ideally, you would like to automate these tests. This
can be done by using the Rational Test Conductor
This is an add-on product to Rational Rhapsody, which
you will take a quick look at later.
Another way to automate these tests is to use an
actor or another class to drive the model.
You will use the class Tester to execute several scenarios.

138
IKeyboard
In order to be able to send messages from the Tester
to the CashRegister, add the event receptions
evStart, evEnd and evCancel to the interface class
IKeyboard.

139
Tester statechart
Add the following statechart to the Tester class.

140
Sub-statechart
Add the following sub-statechart for
the state scenarioAddingProducts.

Use the stub-state enter/exit


connector and name it
S1_DONE.
141
Another sub-statechart
Add the following sub-
statechart for the state
scenarioCancelling
Products.

Use the stub-state enter/exit


connector and name it
S2_DONE.

142
Update EnterExit points
Add the sub-statechart stub connectors enter/exit
connector by selecting Update EnterExit Points.
Connect the sub-statechart stub connectors to the
idle state.

indicates there is a sub-


state.

143
CashRegister port
The CashRegister now needs to do something with
the messages that it receives over the port hw.
Make this port behavioral and realize the interfaces.

144
Save / Generate / Make / Run
Save Generate / Make / Run.
Go.

145
Running a scenario
Open an animated
sequence diagram
based on Behavior.
Generate event evS1
to the Tester object .

146
Removing timeouts
In the previous animated
sequence diagram, the
timeouts are cluttering the
diagram.
There is a property which
determines whether or not
timeout arrows are displayed in
an animated sequence diagram.
Uncheck the following property
and re-run the previous
scenario.

147
Scenario without timeouts

148
Scenario manually entering bar code
Add a new Analysis
sequence diagram
entitled Scenario
manually entering a
barcode.
Realize the un-
realized messages.

149
Event receptions
This scenario should have added two new
event receptions evCode and evKey(n) to
the CashRegister class.
Add an argument n of type int to the
evKey event.
Add these event receptions to the
IKeyboard interface.

150
Managing keys
Add a new attribute to the CashRegister class so that
you can keep track of the key presses.
Add an attribute code of type int, that is initialized to 0.

151
CashRegister statechart
Modify the CashRegister statechart to add the events
evCode and evKey.
Add exit action code=0; to the idle state.

152
Waiting for keys
You now need to get the Tester class to wait for key
presses, but it is already waiting for events. Add a
KeyReader class that waits for keys using cin >> key.
Modify the Tester
Overview diagram to
add the new class
KeyReader.
Add a composition
and a dependency
stereotyped Usage
as shown:

153
Active class
Since the KeyReader class calls cin, it blocks, and
therefore, is an ideal candidate for running on its own
thread.
Set the concurrency of the KeyReader class to active.

Alternatively, you could have set the stereotype


Active. This has the added advantage of adding tags
to the class so that you can specify the periodicity and
worst case execution time.
154
OMThread
Click Active Code View and note that the
KeyReader class inherits from OMThread; this is
another Rational Rhapsody framework class.

Rational Rhapsody creates a thread that runs an


operation in OMThread called execute(). You need to
overload this operation so that it constantly reads the
keys.
155
Overloading execute()
Add an operation execute to the
KeyReader class that returns
OMReactive* and that has the following
implementation:

Deselect this box and enter


the declaration manually.
156
KeyReader parse() operation
Add a private operation parse(char c) to the
KeyReader class with the following implementation:

You may be wondering why this was not


called from within the execute operation.
That was possible, but it was done this way
so you have at least one operation in the
KeyReader class that is animated. This
allows you to set a breakpoint on the
KeyReader thread later on.
157
Tester parse() operation
Add an operation parse(char c) to the Tester
class with implementation:

(c 0) simply converts
an ASCII character
between 0 and 9 to
an integer between 0
and 9.

158
Switching off animation
Since the execute operation never ends, it
does not make sense to animate it.
Select the Animate property to disable the
execute operation from being animated.

Note that there is now no NOTIFY


macro.
159
Starting the thread
To start our KeyReader thread, you must call the
startDispatching operation which is an inherited
operation from OMThread.
You can add a constructor to the Tester class to do this.

160
Thread properties
Set the thread name
for the KeyReader
class.

If you wanted to
execute the model
on a real target, then
you could set various
properties for the
thread of the Tester
class, for example,
the priority, name,
stack size, message queue size, and so on.

161
Execution
Save / Generate / Make / Run / Go.
In the DOS console window, enter:

s <enter>
12345b <enter>
12347b <enter>
c <enter>
e <enter>

You can now use the keyboard to run scenarios.


Check that the model works as expected.
162
Threads
Now that there is an active class you can use the
thread button to inspect the threads.
You can set the focus of the call stack and event
queue to any one thread.
Set the focus to the KeyReader thread.
Set Focus

The animation must be paused to


get access to the thread button.
The call stack shows the actions
and the event queue shows the
pending events just for the current
thread.

163
Setting a breakpoint
Use the breakpoint
command to set a
breakpoint when the
KeyReader thread
gets control.
Go , then in the
DOS console window
enter command:
s <enter>

164
Updating the use case
Now that you have created some
sequence diagrams, you can
associate them with the use case
Keep count of selected products.

165
Use Case 3

Generate a ticket
showing total cost

166
Generate a ticket use case
In order to generate a ticket, you need to be able to
count how many there are of each product. To do so,
you will introduce a new class CountedProduct.
Create a new OMD in the package CashRegisterPkg called
Product Overview.
Draw class CountedProduct and
drag CashRegister and Product
classes onto the diagram.

Remove the port from the CashRegister in


this view. Right-click then select Ports >
Hide All Ports.

167
CountedProduct
Add generalization.
Add qualified association with multiplicity *
Add attribute count of type int initialized to 1
Set the property to generate an accessor for count.

168
getPrice() / increment()
Add operations getPrice() and increment().

169
CountedProduct constructor 1
You will be creating CountedProducts from Products
so you need a constructor that takes a Product as
an argument with direction In.
Add the constructor.

170
CountedProduct constructor 2
As for the Product class, you do not need an implicit
constructor for the CountedProduct class.
Set the following property:

171
Another product constructor
Add another constructor to the Product class, that is
public and that takes Product as an argument.

172
Adding a scenario
Add an Analysis sequence diagram
entitled Scenario generating a ticket.
Drag the classes from the browser
onto the diagram.
Double-click on each instance of CountedProduct to
enter the specific instance name.

173
Completing the scenario
Complete the
scenario and realize
the messages.

174
print() operation
The print() operation is shown as
being invoked on the Tester
class. In fact, it is being invoked
on the IPrinter Interface class.
Add an argument aMsg of type
char* to the Tester print()
operation and then copy it to the
Interface class IPrinter. Press
Ctrl while dragging it.

175
print() operation implementation
Add the following implementation to the print()
operation of the Tester class.

176
CountProducts operation
For the CashRegister class, add the
implementation for the operation
countProducts().

177
generateTicket() operation
For the CashRegister class, add the
implementation for the operation
generateTicket() .

178
endSession()
You need to modify the endSession()
operation so that you remove all the
CountedProducts and delete them.

179
Printing a ticket
Save.
Generate / Make /
Run.
Use the DOS console to start
a session, enter some
barcodes, and then end the
session.

180
Using the tester to print a ticket
Add a new state scenarioGeneratingTicket to the
Tester class, so you can easily test out the model.

181
randomShopping
Add a private operation randomShopping to the
Tester class.

182
Executing the scenario
Save / Generate / Make / Run / Go.
Send event evS3 to the Tester.

183
Referenced sequence diagrams
Add the sequence diagram Scenario generating a
ticket to the use case Generating a ticket showing
total cost.

184
Extended exercise
Add a new Sequence Diagram Ticket as follows:
Ensure that the Name is *.

185
Automatic creation of instance lines
Close all windows.
Run / Go.
Set breakpoint.
Inject evS3 to the Tester.
When breakpoint
reached, open animated
sequence diagram based
on Ticket.
Go.

186
Automatic creation of instance lines

187
Use case 4

Manage special
offers

188
Special offer use case
Open the Product Overview OMD and add an
interface entitled ISpecialOffer.
Add an aggregation from Product to
ISpecialOffer.

189
Directed aggregation
Change the relation to be
directional and not
symmetrical.
Change the role name to
be itsSpecialOffer.
Set Multiplicity to 0,1.

190
getSpecialPrice() operation
Add an operation getSpecialPrice() which returns int.
Add arguments unitPrice and quantity both of type int.

191
Special offers overview
In CashRegisterPkg,
add a new OMD
entitled Special Offers
Overview.

If you checked Automatically


show this window the last time
you used the Implement Base
Classes, then this window appears
automatically each time you draw
the inheritance. If it does appear,
close it down.
192
BuyOneGetOneFree
Select the BuyOneGetOneFree class, right-click and
select Realize Base Classes.

193
Implement base classes
You must implement the getSpecialPrice()
operation, so check the operation and select
Edit Code to enter the implementation:

194
Extended exercise
Implement the getSpecialPrice() operation for
the other classes that realize ISpecialOffer:

195
Using the special offer
Modify the ProductDatabase Overview OMD.
Add the BuyOneGetOneFree class with a dependency
from ProductDatabase to it. With the features for this
dependency, set the stereotype to Usage.

The Usage stereotype


generates a #include
BuyOneGetOneFree.h.

196
Applying the special offer
Modify the implementation of the
ProductDatabase constructor.

197
Product constructors
Modify the Product
constructors.

198
CountedProduct getPrice()
Modify the implementation of the
getPrice() operation of the
CountedProduct class:

199
Generate Ticket()
Modify the
generateTicket()
operation of the
CashRegister
class.

200
Kiwis are buy one get one free
Save / Generate / Make / Run / Go.
Send event evS3 to the Tester.

201
Requirements revisited
Now that you have finished the use cases, you can
check that you have implemented all the
requirements by adding dependencies with
appropriate stereotypes.

202
Requirements coverage
Switching back to the Rational Rhapsody Gateway, you
should now see that you have coverage for REQ5:

203
Moving events
Finally, the Tester should not
know at all about the
CashRegisterPkg, so it is
better to move all the events
to the InterfacesPkg. Press
Shift, and select all the
events, and move them.

204
Extended exercise

Web GUI

205
Changing the hardware
Ideally, you want to be able to run this model on a
different hardware platform.
In this case, you would need to replace the
TesterPkg; the CashRegisterPkg would not change
at all.
See how this is done by creating a GuiPkg that uses
webify to create a webified GUI that can be used to
drive the model.
Add a new package to the HardwarePkg called
GuiPkg.

206
GUI overview
Add an OMD called GUI Overview to the GuiPkg
package.
Add GuiHardware class and copy the port from the
Tester class.

207
GuiBuilder
Add a GuiBuilder Class and add a structure diagram
to it.
Add objects and link.

208
GuiPrototype
Make a copy of
TesterPrototype
component,
rename it to
GuiPrototype.
Modify the Scope
so it includes the
GuiPkg and not the
TesterPkg.
Modify the initial
instances to create
just an initial
instance of a
GuiBuilder.
209
Web enable
Web enable the GuiPrototype component.

210
Attributes
Add the following attributes, all of type OMString, to
the GuiHardware class, and set stereotype
FullWebManaged.

211
Operations
Add the following operations, all with stereotype
Web Managed.

212
More operations
Ensure that the GuiHardware class realizes
both IDisplay and IPrinter.
Use Realize Base Classes
to add show and print
operations.

213
http://localhost/
Add a hyperlink to localhost.
Save , Generate / Make /
Run , Go
Open the hyperlink
http://localhost/

214
Improving the Web page 1
By writing some HTML, some GIFs, and some
JavaScript, you can easily improve the GUI.
Add the following files to the GuiPkg as
ControlledFiles:

You could add these controlled


files to the GUI Overview
diagram to show that the
GuiHardware depends on them.

215
Improving the Web page 2
Add the four files to the GuiPrototype Component.
Apply to each file, the WebManaged stereotype,
set the type to Other, and set the path to
..\..\CashRegister_rpy.
Add a hyperlink to the Web page
http://localhost/CashRegister.htm.

216
http://localhost/cashregister.htm

End

Cancel

Keys 0-9

Code Start

217
Summary
This case study has shown you how you can start
with requirements and gradually implement them
use case by use case. During this case study, you
have learned how to:
Use profiles.
Manage requirements.
Capture scenarios using sequence diagrams.
Use ports to create reusable components.
Manage one to many relations.
Create threads.

218

IBM Software Group

Essentials of IBM Rational Rhapsody v7.5 for Software


Engineers (C++)
Advanced Rational Rhapsody

2009 IBM Corporation


Objectives
Now that you know the basics about Rational
Rhapsody, you should be able to start creating your
own projects. To confirm this, try to create a simple
project without any step-by-step instructions. There
are also many more topics that a developer needs to
understand and so by the end of this section, you
should have an understanding of topics such as:
The Rational Rhapsody Framework
Generating reports
Using the API
Using Configuration Management
Rational Rhapsody TestConductor

2
Advanced Rational Rhapsody
Triggered Operations
Introduction to the Rational Rhapsody Framework
More about Containers
Managing Interrupts
Generating Reports
Using the COM API
Using the Java API
Introduction to Configuration Management
Introduction to Rational Rhapsody TestConductor
Stopwatch Exercise
Speed Camera Exercise
Useful Tips

3
Advanced Rational Rhapsody

Triggered
operations

4
Sending an event
In the DishwasherSystem created previously
(Dishwasher if you did not save the model as
DishwasherSystem model), events such as evStart
were sent from the FrontPanel to the Dishwasher.
The event was queued and then executed after a
certain delay that depends on how many other events
are in the event queue. The delay depends on how
many other events are in the event queue and as
such is not very deterministic.
Another potential problem is that the FrontPanel
could send events faster than the Dishwasher could
handle them in which case the event queue might
overflow.
A solution to these problems is to use a triggered
operation which is basically a synchronous event,
also known as a blocking call.
5
Triggered operation
A triggered operation can be used on a
transition in a Statechart the same way as an event.
For example, you can change all the events in the
dishwasher to be triggered operations. It is often a
good idea to also change the prefix ev to tg.

6
Calling the triggered operations
You can modify the processKey() operation in the
FrontPanel to call the triggered operations:

The syntax for


calling a triggered
operation is the
same as for an
operation.

7
Sequence diagram
When executing the Synchronous call

model, you can see the


difference between an
event and a triggered
operation:

Asynchronous call
8
Triggered operation code

Statechart
transition blocks
the caller.

9
Invoking triggered operations
In order to invoke a
triggered operation or a
primitive operation from
the animation bar, it is
best to first use the
Advanced settings and
set Enable Operation
Calls to Public or All.

10
Calling operations
Once the code is regenerated and rebuilt, the
key can be used to invoke operations.

11
Advanced Rational Rhapsody

Introduction to the
Rational Rhapsody
framework

12
Framework
The Rational Rhapsody framework is a collection of
base classes and interfaces that are used by the
code generated from a users model.
Rational Rhapsody

External
Generated Code

Code
OXF Framework
RTOS
CPU

There are two main parts to this framework:


1. The Object eXecution Framework (OXF), which is the part
of the framework that will always be linked into the final
generated code.
2. The Animation and Tracing Framework, which is only used
when animating or tracing and as such is less important to
understand than the OXF.

13
Object eXecution Framework organization
The OXF Framework is created directly from a
Rational Rhapsody model.
(See <RhapsodyInstall>\Share\LangCpp\oxf\model\oxf.rpy).
There are three main parts to the Object eXecution
Framework
1. Event Driven Framework (Core and Core Implementation
package)
2. Operating System Adapter Layer (Adapters package)
3. Container Classes (Part of Services package)
Rational Rhapsody
External

Generated Code
Code

OXF Framework
RTOS Event Driven Framework
CPU Container
Classes
Operating System Adapter Layer

14
Object eXecution framework model
The OXF Framework consists of many different
nested packages enabling it to be built in a scaleable
fashion to include only the required functionality.
There is a set of
interfaces in CoreAPI and
a default implementation
in CoreImplementation for
the framework behavior.
This allows you provide
your own Implementation
yet not break the
automated code
generation process.
15
Event driven framework interfaces
These are the principal interface classes in the
Event Driven Framework:
IOxfActive
IOxfReactive
IOxfEvent
IOxfTimeout

16
Event driven framework implementation
These are the principal classes of the default Event
Driven Framework implementation:
OMThread
OMReactive
OMEvent
OMTimeout
OMProtected
OMTimerManager
OMMemoryManager

17
OMEvent
OMEvent Base class for all signal and timed events:
 OMEvents have an unique ID.
 They know the address of their
destination (receiving reactive
object).
 There are specific Framework
events for internal usage.
 Events may or may not be
deleted after consumption (if static).
 They may provide their own custom
destroy() operation, for example, to
reuse the event in a memory pool.

18
OMTimeout
OMTimeout Base class for all Rational Rhapsody
timed events:
 They inherit everything from
OMEvent.
 OMTimeout events have a
special ID.
 They add a delay time attribute.
 They may be canceled before
they matured, but also after
already being queued.

19
OMReactive
OMReactive Base class for all reactive classes (for
example, all classes with statecharts).
OMReactive knows the thread it runs on.
It provides send() operations in order to
put events into the input message queue
of its active class via OMThread::queue().
It provides the operations handleEvent()
(for asynchronous signal events) and
handleTrigger() (for synchronous events).
It provides operations to schedule and
cancel relative timeouts.
Finally it defines virtual operations for the
code generator in order to implement the
statemachine of the application class, for
example, rootState_processEvent().
20
OMThread
OMThread Base class for all active objects for
multi-threaded applications.
OMThread creates one event
Queue and a dispatchingGuard
and runs its execute()
operation in an operating
system thread.
The operation queue() allows
you to put events of type
IOxfEvent into the message
queue.
execute() by default reads
messages from the queue and
dispatch() them calling the
reactive destinations
handleEvent().
21
OMThread
Each OXF thread waits on an event queue for
incoming events:
OMReactive* OMThread::execute() {
for ( ;; ) {
while ( !eventQueue->isEmpty() ) {
IOxfEvent *event = eventQueue->get();
IOxfReactive *dest = event->getDestination();
dest->handleEvent(event);
delete event;
}
eventQueue->pend();
}
}

The above is a simplified version of the main loop


operation in an OXF thread. It is named execute().
This operation may be overloaded in order to read
from other blocking devices, rather than read OXF
message queues. This is what was done in the
KeyReader class in the CashRegister example.
22
Client server OXF sequence - sending

23
Client server OXF sequence - receiving

24
OMProtected
OMProtected is used to
protect an operation from
concurrent access. To do
so, set the property
CG:Operation:Concurrency
from sequential to guarded.
This protects this operation
with OMProtected (which is
basically a mutex).

For more info, see the


OMProtected.h file.

25
OMMemoryManager
The framework includes a memory manager that
overrides new and delete to allocate memory.

For more info, see the


OMMemoryManager.h file.
26
Extending memory management
There are two ways to override memory allocation:
 Use the static architecture
properties so that memory will
be allocated statically using
memory pools.
 Provide a custom memory
manager class.

27
Interrupt driven framework
By using the interrupt driven framework
(IDF), it is possible to use Rational
Rhapsody in C++ without the need for an
Operating System.
The IDF can replace the OXF and RTOS.
It generates smaller code.
Requires just a periodic interrupt to be
configured (so that timeouts can be used
in statecharts).
The IDF is supplied in a Rational
Rhapsody in C++ model
RiCpp_InterruptDrivenFramework.rpy.
Rational Rhapsody
External

Generated Code For more info, see the documentation included in


Code

IDF Framework the V73_RiCpp_InterruptDrivenFramework model.


CPU
28
Synchronous framework
The standard frameworks ( OXF and IDF ) both allow
asynchronous and synchronous communication.
If only synchronous communication is desired so that
the behavior is deterministic, then triggered operations
can be used instead of events. Rational Rhapsody

External
Generated Code

Code
In this case, the majority of the SF Framework
framework is redundant. CPU

The Synchronous Framework is just the bare


minimum framework necessary to allow the use of
triggered operations.
The Synchronous Framework does not require an OS.
and as such, active classes are not supported.
Timeouts and events are not supported.
Has a smaller footprint than the IDF.

29
No framework
If the framework is not required, then you can simply
set the stereotype NoFramework to the
configuration.
Of course without the framework, there will be no
code generation for active classes, ports, state
charts, relations with unbounded multiplicity and so
on.

This stereotype is provided in


the same profile used during
the CashRegister exercise.

30
Container classes
Template based containers
OMList<Concept>
OMCollection<Concept>
OMMap<Key,Concept>
OMIterator<Concept>
Untyped containers (do not use templates)
OMUList
OMUCollection
OMUMap
OMUIterator
Miscellaneous These classes are in
Rhapsody\Share\LangCpp\oxf.
OMString
OMBoolean
31
Operating system adapter layer
In order to be able to work with almost any Operating
System, Rational Rhapsody provides a thin Operating
System Adapter Layer that describes the services
required of an OS.
When ever the application needs to use an OS
service such as creating a mutex, it does so via this
adapter layer.
This gives the advantage of being able to easily
interchange Operating Systems, such as being able
to test on the host using Windows, then deploying on
a target with INTEGRITY, VxWorks, Windows CE,
OSE, Nucleus, Linux, ThreadX, QNX, pSOS
The adapter layer is implemented using the Abstract
Factory design pattern. 32
Adapter interface

33
NT adapter

34
VxWorks adapter

35
INTEGRITY adapter

36
Nucleus adapter

OMOSFactory

NuOSFactory

OMOSThread OMOSEventFlag OMOSMutex OMOSMessageQueue OMOSTimer OMOSSemaphore

NuThread NuOSEventFlag NuMutex NuOSMessageQueue NuTimer NuOSSemaphore

37
Using the adapter
For example to use a mutex:
Create an attribute of type OMOSMutex*:
OMOSMutex* itsMutex;
Create using :
itsMutex = OMOSFactory::instance()-
>createOMOSMutex();
Locking:
itsMutex->lock();
Unlocking:
itsMutex->unlock();

If you use this method for


creating event flags,
mutexes, and semaphores,
then it works on all OSs.
38
Advanced Rational Rhapsody

More about
containers

39
OMContainers
You have seen that for
the relation of
multiplicity *, Rational
Rhapsody generates
the following:

OMList<Observer*>

OMCollection<Observer*>

OMMap<int,Observer*>

40
Using an OMContainer

41
STLContainers
If you set the property
ContainerSet to
STLContainers, then
Rational Rhapsody uses
the STL (standard
template library).

list<Observer*>

vector<Observer*>

map<int,Observer*>

42
Using an STL container

Make sure that you use


++iter rather than iter++,
since this avoids the
creation of a temporary
object.

43
OMUContainers
If you set the property
ContainerSet to
OMUContainers then
Rational Rhapsody uses
the untyped containers:

OMUList

OMUCollection

OMUMap

44
Using an OMUContainer

These containers do not use


templates. Templates can
sometimes be a problem for
some compilers.

45
Static arrays
Sometimes it is more efficient (though less safe) to
use a static array.
To use a static array, the multiplicity must be
bounded, for example, MAX_OBSERVERS.

46
Advanced Rational Rhapsody

Managing interrupts

47
Interrupt service routines
Setting up interrupt service routines varies from one
CPU to another and from one OS to another. With
Rational Rhapsody, you should use the same method
you would use without Rational Rhapsody.
Example: with VxWorks:
The ISR routine must be static and non-animated.

48
Sending events from ISR routines
To send an event from an ISR routine, there is a
special macro GEN_ISR that can be used.

See the
InterruptHandler
model for more
info.
49
Advanced Rational Rhapsody

Generating reports

50
Reports
There are two ways in which you can generate a report,
Report on model or ReporterPlus.
The first way is to select Tools > Report on model to
generate a quick but simple rtf format file:

51
Report on model
This generates a
simple rich text
format (RTF) file.
The report
generation is very
quick, but there is
little control over
the formatting.

52
Rational Rhapsody ReporterPLUS
With the Rational Rhapsody ReporterPLUS, you can
generate HTML, RTF, Word or PowerPoint files. You
can also use off the shelf or customize your own
templates to format the documentation as you want.
Rational Rhapsody ReporterPLUS has a graphical
IDE for creating templates.

53
Rational Rhapsody ReporterPLUS IDE

The IDE allows


templates to be
created graphically
by drag and drop.

54
CashRegister.doc

55
CashRegister.html

56
Advanced Rational Rhapsody

Using the COM API

57
Simple VBA macro
In the Case Study, you
entered several use case
descriptions, all of which
were based on the same
template.
You can create a VBA
macro to facilitate this.
Start the Visual Basic
editor.

58
Module
Insert a new module:

59
Writing a macro
Write the following macro then select File >
Close and Return to Rhapsody.

60
Adding a helper
You want to be able to
call this macro whenever
you are working with a
use case.
Add a helper as follows:

61
Calling the macro
The macro can now be invoked by right-clicking on
any use-case.

This simple macro only


formats use cases that
have an empty
description.

62
Advanced Rational Rhapsody

Using the Java API

63
Simple Java program
Instead of using VBA and the COM API, you can
use the Java API to format the use case.
You can use Eclipse to create a Java project that
references the Rational Rhapsody Java API:

64
FormatUseCaseHelper.java

65
Running the Java program
To run the Java program
from within the Eclipse
environment or the VBA
macro, you can add a
helper to invoke the
program by right-clicking
on a use case.

-Djava.class.path=$OMROOT\javaApi\rhapsody.jar;D:\eclipse\JavaApps\FormatUseCaseHelper -
Djava.library.path=$OMROOT\javaApi com.rhapsody.helpers.FormatUseCaseHelper

66
Rational Rhapsody plug-in
To get better
performance
from the Java
program, write
it as a Rational
Rhapsody
plug-in and
then create a
jar file from it.

67
Helper file: FormatUseCase.hep
Write a helper file so that the plug-in gets loaded
every time that Rational Rhapsody starts.

68
Loading a helper file
Add the following to the site.prp or siteC++.prp file to
load the helper file:

Now, next time that Rational Rhapsody is started,


you can format a use case example.

69
Model checker
Some checks are run every time that code is
generated, for example checking to ensure that there
is a default transition.
You can run the same checks as well as others using
Tools > Check Model.

70
Custom checks
You can use the API to write your own model
checks that can be added to the built in checks.
For example you could add checks to do the
following:
1. Ensure that if a history connector is present, then it is
initialized.
2. Ensure that there are no redundant classes, (generally
these are classes that were added inadvertently and
usually have a name that ends in _0, _1, ).
3. Ensure that there are not any possible redundant
relations, generally these are classes that were added
inadvertently and usually have a name that ends in _1,
_2, ).

71
CustomChecksHelper

72
HistoryCheck

See
CustomChecksHelper.zip
for complete code.

73
Helper file
The checks can be added via a Helper file:

74
Custom checks
Every time that Rational Rhapsody generates code,
the custom checks are executed.

75
Advanced Rational Rhapsody

Introduction to
configuration
management

76
Configuration management
Rational Rhapsody can attach to many CM tools
such as Rational Synergy, PVCS Dimensions, PVCS
Version Manager, Rational ClearCase, Visual
SourceSafe, SourceIntegrity, and so on.
The connection can be done by using either the
SCC interface or the command line interface. The
selection is made in the project properties (or can be
setup in the site.prp file).
Rational Rhapsody checks in and out parts of the
model, these parts are called units.
Units checked out without a lock are read-only.
In order to work with Subversion or CVS, then an SCC
plug-in must be obtained, for example, PushOk.

77
CM units
These are the types of units that can be
checked in/out with the CM tool:
project .rpy files
packages / profiles .sbs files
object model diagrams .omd files
structure diagrams .std files
sequence diagrams .msc files
components .cmp files
use case diagrams .ucd files
classes, actors & use cases .cls files
collaboration diagrams .clb files
component diagrams .ctd files
deployment diagrams .dpd files
panel diagrams .pld files
controlled files 78
any extension
Units
Each unit can be seen in the browser as having the
symbol.
By default, only components, controlled files,
profiles, and packages are units.
By default, diagrams, classes, actors, and use cases
are not units.
To be able to check in/out a single diagram / class /
actor or use case, select it in the browser, right-click,
and select Create Unit.

Unit
79
SCC or command-line interface
Before using the
Configuration
Management, you must
decide whether to use
the SCC interface or the
command-line interface.

To understand more about which


method to use, check out the
document:
\Doc\pdf_docs\team_collab_guide.pdf.

80
Configuration management options
Before using the
configuration
management, there
are various options
that may need
setting, for example,
what should happen if
a model element gets
deleted, moved, or
renamed.

81
Using the SCC interface

Flat view Tree view

82
Step 1: Connect to archive
The first step is to connect to the archive:

The menus presented


may be different,
depending on the CM
tool present. The
menus shown here
are for Visual
SourceSafe.

83
Step 2: Add to archive
Once connected to the archive, the model elements
need to be added to the archive.
The simplest way to do this is to use the Tree view,
select the project, and then select Add to Archive.

84
Step 3: Checking out files
Any model element that
is checked in is read-
only.
In order to work on that
model element, you
need to check it out.

85
What has changed?
To see the difference between
the current model and the
archive, select the unit and press
the Diff with Rhapsody key.

To see the difference


between two different
models, use the
Rational Rhapsody
DiffMerge tool.
86
Rational Rhapsody DiffMerge tool
The two browsers are interposed. The Symbols
indicate where there are differences between
the models.

87
Viewing model differences
You can view just the model differences:

88
Ignoring graphical differences
By default, Rational Rhapsody DiffMerge
ignores any changes that are just
graphical, for example, where a class has
been moved on a diagram.

89
Viewing the diagram differences
The differences can be all highlighted by using the
button.
The button can be used to highlight the first
difference and the button used to highlight each
subsequent difference.

90
Merging
The Rational Rhapsody DiffMerge tool can
be used to merge two models into one.
The merge is started by using the button.
Either of the models can be used as a starting point
by using the buttons.
Then, model elements can be selected one by one.
Finally, the merged model can be saved or merged
back to Rational Rhapsody.

91
Base-aware merge
A base-aware merge can be done; ideally, this is
connected to a CM tool such as Rational Synergy or
Rational ClearCase to allow automatic merging.
The Rational Rhapsody DiffMerge can be run to
perform a base-aware comparison and merge.

92
Base-aware Diff

93
CM status
When using the SCC
interface, you can display
the status of each model
element in the browser:

This package has no


symbol, since it is not yet
Controlled by CM.
94
Add to model
Add to model can be used to import units
from another model.
The model can either be added to the
model as a unit (a Read-Write copy) or as
a reference (Read-Only Reference).
If Add Dependents
selected, then all
dependent units are
be added.

95
Working with large projects
When working on a large model, you
often only need to work on just one
package at a time. Rather than loading
the entire model into Rational
Rhapsody, you can load just the units
that you want to work with. Select Without
Subunits

Units can also


be unloaded.

96
Loading units
The model is opened and
none of the units are
loaded. They have a
symbol (U) indicating that
they are unloaded.
To load a unit, right-click
and load the unit either
with or without the
subunits (nested units).

97
Advanced Rational Rhapsody

Introduction to Rational
Rhapsody TestConductor

98
TestingProfile
The Rational Rhapsody
TestingProfile provides a number
of stereotypes conforming to the
UML Testing Profile:
SUT
TestCase
TestObjective
TestContext
TestComponent
TestConfiguration


99
Testing phases
Create a Test Architecture
 In order to start testing, you first need to select the
classes which you want to test. Then, create a test
architecture for them, so that you can test it
independently of the rest of the system. Creating this Test
Architecture can be done either manually or
automatically.
Create Test Cases
 Test Cases can be written in one of two ways, either:
Graphically via sequence diagrams
Manually via code, activity diagrams, or flow charts
Execute Test Cases
 The test cases can be executed either interactively or in
batch mode, and any errors reported and analyzed.

100
Testing artifacts
All testing artifacts are UML
model elements and can be
managed with configuration
management in the same way
as any other Rational
Rhapsody model element:

101
Test architecture
A test architecture can be created by selecting a
class to test and then creating a test architecture
similar to the following:

102
TestScenario
Once you have a test architecture, you can
start to describe test scenarios using sequence
diagrams such as the following:

103
Test Case: based on test scenarios
A TestCase can play back
a number of TestScenarios
in a specific order to verify
that the messages received
are as expected.
Each TestScenario may be
parameterized and used
several times with different
parameters.

104
Manual test cases
If you have some complex structures that you want
to pass, or want to check return values or output
values, then this is difficult to do graphically with
sequence diagrams. In these cases, you can write
some manual test cases. You can either manually
write the code or you can use a flow chart:

105
Building the test context
Before the TestCases can be run,
the TestContext must be built.

106
Executing the TestContext
Each TestCase can be run:

107
Test results
After the test completes, a
Test Result and a
CoverageResult is added to
the TestCase.

108
Running all the test cases
All the TestCases can be run in
mode batch:

109
Code coverage
Animation can be switched off for the SUT. This
allows Rational Rhapsody TestConductor to be used
with tools, such as Rational Test RealTime, in order
to get the Dynamic Code Coverage. With Dynamic
Code Coverage, you are assured there is no unused
code.

110
Failed test
If a test fails, then a sequence diagram can be
automatically added to the model to help analyze the
problem:
Incorrectly
received
message

Correctly
received
message

Expected
message

111
Advanced Rational Rhapsody

Stopwatch
exercise

112
Stopwatch exercise
The goal is to build a simple stopwatch that has a
single button and a display. The stopwatch displays
minutes and seconds up to a maximum of 99
minutes and 59 seconds.
Every time the button is pressed and released within
two seconds, the stopwatch is started/stopped.
However, if the button is held pressed for longer than
two seconds, then the stopwatch is reset to 0.

113
More details
Imagine that an ISR (interrupt service
routine) triggers every time that a key is
pressed or released and generates
events evPress or evRelease.
A colon symbol between the minutes and
the seconds 00:04 should be flashed to
indicate that the Stopwatch is running.
Build a model of a stopwatch that can be
stopped, started, and reset by injecting
events evPress and evRelease.

114
Advanced Rational Rhapsody

Speed camera
exercise

115
Speed camera exercise
The goal is to build a Speed Camera System. This system will
have four cameras which will be installed at equal intervals. It
should be easy to change the number of cameras. Each
camera is capable of reading and decoding a number plate of a
vehicle. Whenever a vehicle passes a camera, the number
plate is read and sent to the Speed Camera System.
The Speed Camera System checks the average speed between
adjacent cameras. If any vehicle takes less than the allowed
time (combination of the speed limit and the distance between
cameras) to pass between two cameras, then it is reported as
speeding.
After a vehicle passes the last camera, any retained information
should be discarded.
Assume that every Camera receives the event
evVehicle(aNumberPlate) every time that a vehicle passes.
The Speed Camera System should print out the number plates
of all detected vehicles that are speeding.
116
Advanced Rational Rhapsody

Useful tips

117
Useful tips 1
Keep statecharts simple; if they are too complex,
then use sub-statecharts.
Draw states as small as possible and as close as
possible to other states. This helps during
animating, since they are more readable, especially
when there are several diagrams open at the same
time.
Do not call many actions on a statechart; it makes
the diagram very difficult to read. Instead, call a new
operation that calls the actions.
To aid navigation within the model, set up
hyperlinks for every use case, class, and package.

118
Useful tips 2
Look at the Rational Rhapsody samples and revisit
the Cash Register model that you built during this
training. Make sure that you understand these
models before you start a project.
Do not give the same name to several different
elements of the model, example package and class.
The generated files overwrite each other.
When working with large projects, it is essential to
divide up the model into components. The
interfaces between these components should be
well-defined. Then, work can be carried out
simultaneously and independently by different
teams on each component.
119
Useful tips 3
Do not put everything onto a single diagram; this
can make reading the diagram difficult. Using a
couple of diagrams, depicting different views can
really help in communicating the model.
Use an iterative approach similar to that taken
during this training, constantly model / save /
generate / make / run. Do not wait until the model
is too large before animating.
Each diagram should have a mission, a reason
why it is there, and should be named in such a way
as to reflect this.

120
Useful naming conventions
Start Event names with ev:
For example, evStart
Start Triggered operation with tg: These conventions help
For example, tgPress when reading diagrams
and when recalling
Start Condition operations with is: names of model
elements.
For example, isPressed()
Start Interface classes with an I:
For example, IHardware
Start Classes with an UpperCase, operations and
attributes with a lowerCase.
Use an UpperCase to separate concatenated words,
for example, restartSecondTimer().
121
Advanced Rational Rhapsody

Avoiding common
mistakes

122
Dead lock situation 1

9
123
Dead lock situation 2

124
Transition or reaction in state?

Reactions in state

125
Null transitions
Each time a state is entered, Rational Rhapsody
checks to see if there is a null transition that could be
taken. If there is, then the transition is taken.
In the following example, there is no stable state since
every state has a null transition with a guard that evaluates
to True.
In this case, the following message is displayed: Infinite
loop of Null Transitions.

A Null Transition
is a transition that
has no trigger.

126
What is done first?
When in the waiting state, what happens when the
evCoin event is received?

Answer : The value of coin is tested BEFORE it gets assigned!

127
Attribute access
Setting the access for an attribute modifies the access
for the accessor and mutator, not for the attribute
itself. Attributes by default are always protected.

128
Generate support request
Rational Rhapsody includes a special function that
facilitates sending an email to Technical Support.
This function collects information about your system
and the Rational Rhapsody environment and model,
then creates a zip file.
This zip file can then be sent to IBM.
Alternatively, the zip file can be transferred to another
machine and emailed.

129
Support request

Quickly collects
problem information

Information about
Rational Rhapsody and
system automatically
collected

130
Adding files, screen shots, videos, and so on
Videos can be
captured to aid
problem description

Model and extra files


can be quickly added

Screen shots
can be
captured

131
Sending the email

All models, files, and screen shots are automatically


zipped and attached.
132
eLearning
eLearning is Web-based, self-paced training.
Interactive multi-media
features:
Demonstrations
You try it exercises
In lesson quizzes with feedback
Post tests to ensure knowledge has been acquired
Intended as an introduction to:
Modeling languages
Advanced topics
Add-on products

133
eLearning: Current Courses
For a listing of all courses offered, visit us at:
http://www.ibm.com/training

134
Recommended Reading

135
Summary
You should now know enough about Rational
Rhapsody to start creating your own projects. You
should have basic familiarity with the following topics:
The Rational Rhapsody Framework
Generating reports
Using the API
Using Configuration Management
Rational Rhapsody TestConductor
To develop more in depth skill and knowledge about
the topics above, there is additional Rational
Rhapsody Specialist training available.
Please fill in the online evaluation form your instructor
guides you to or complete the evaluation at the end of
this manual, good luck and keep in touch.
136
Evaluation Form
Prior to this course, how would you rate your knowledge of the following?
UML ______ 5 = Excellent
C++ ____ 0 = Poor
How would you rate the following aspects of the course?
Overall course ______
Organization of topics ______
Usefulness of topics ______
Usefulness of labs / exercises ______
Course materials ____
How would you rate the instructor in terms of the following?
Overall effectiveness ______
Knowledge of subject ______
Stimulated and held interest ______
Organizational skills ______
Provided ample time for questions ______
Addressed questions well ______
Gave clear instructions for labs, etc. _______

137
Name (optional) : Date :
Company : Instructor :

Were there any topics which seemed difficult to understand?


Are there any topics, which were not covered, that you feel should be?
Do you have any suggestions for improving the course and/or the course materials?
What was most effective about the instructors presentation?
Do you have any suggestions for improving the instructors presentation?
Do you feel that the course has met its objective?
Would you recommend this course to a colleague?
Please provide their details, if we may contact them:

138

Vous aimerez peut-être aussi