Multiple Statements Loops in UML 1.5
Summary
UML 1.5 offers a rich notation for capturing system static and dynamic behaviour. Nevertheless, some simple situations are tricky to handle. For example a simple loop in an interaction diagram (sequence diagram or collaboration diagram) containing multiple statements.
This article offers a possible solution.
The UML notation for iterations
The Unified Modeling Language User Guide, chapter 18, (edition April 2002) states:
"An iteration represents a repeated sequence of messages.
To model an iteration, you prefix the sequence number of the message
with an iteration expression such as: *[i:= 1..n] (or
just * if you want to indicate iteration but don't want to specify
its details)."
This is pretty much all that you will find about writing an iteration in UML! Even the UML specification is vague on this question. It is enough for most situations.

However it is not sufficient as soon as you need to identify multiple statements inside the loop! Consider the situation where we have two different method calls (doFoo() and doOtherFoo()) within the same loop. How might we illustrate this with UML?
the following is a possible representation:

If we follow this diagram and produce Java code from it we would end up with two separate loops as shown below:
{
Foo foo = new Foo();
for (int i = 1; i<=10; i++){
foo.doFoo();
}
for (int i = 1; i<=10; i++){
foo.doOtherFoo();
}
}
But what we are looking for is in fact is the following:
{
Foo foo = new Foo();
for (int i = 1; i<=10; i++){
foo.doFoo();
foo.doOtherFoo();
}
}
The problem is excerbated if inside the loop we wish to call methods belonging to different objects:
{
Foo foo = new Foo();
FooBar fooBar = new FooBar();
for (int i = 1; i<=10; i++){
foo.doFoo();
fooBar.doFooBar();
}
}
Let's see our different solutions.
The pure UML solution: Refactoring
If we want to stick to the pure UML notation we have to be creative! As a result the code will be slightly modified as we will see.
What can we do when we have only one statement inside the loop when want two or more?
The solution is to create a separate method holding the multiple statements and call this method from inside our loop.
Where shall we place this method?
The cleanest place is inside the class containing the loop itself
and we will call this method loopContent(). To maintain
a better level of encapsulation this method is made private. The
interaction diagram for this now looks like the following:

class Bar {
Foo foo = new Foo();
FooBar fooBar = new FooBar();
void private loopContent(){
foo.doFoo();
fooBar.doFooBar();
}
void doBar(){...}
}
The Sequence diagram for the method Bar.doBar() is now:

The code for the Bar class becomes:
class Bar {
Foo foo = new Foo();
FooBar fooBar = new FooBar();
void private loopContent(){
foo.doFoo();
fooBar.doFooBar();
}
void doBar(){
for (int i=1; i<=10; i++){
loopContent();
}
}
}
This can be seen as a good solution in that it respects the UML notation however we have created a redundant method as it is only inside this loop and the diagrams are now more complicated to understand by splitting a simple concept into two diagrams.
From experience this solution might be pure UML, but it is also very confusing and most people do not understand the reason for the loopContent() method. They are actually right as it is very difficult to justify from a design perspective.
So what can we do?
Proposal for a notation: adding semantic meaning to the index name
A simple solution is to add a semantic meaning to the name of the index. The rule would be: when two methods calls are in the same loop, they use the same index identifier.
The first diagram we had would now respect this convention as both methods calls use the same index identifier i, and are therefore interpreted as being in the same loop:

The code is now correct.
{
Foo foo = new Foo();
for (int i = 1; i<=10; i++){
foo.doFoo();
foo.doOtherFoo();
}
}
The use of two different names would be for creating two separate loops:

{
Foo foo = new Foo();
for (int i = 1; i<=10; i++){
foo.doFoo();
}
for (int k = 1; i<=10; i++){
foo.doOtherFoo();
}
}
This notation is simple to use, but has the weakness that we have added a meaning to using the loop index identifier for method calls which is not formally defined within the specification. It is also probably difficult to describe this notation in the UML meta-model.
Tools such as Rose, Control Center, Poseidon, Enterprise Architect, Visio, have different ways of handling this situation.
Conclusion
UML is a great step towards improving communication within the software development team. It is generic enough to probably cover more situations than you are likely to encounter but it does have some weaknesses.
This article has highlighted one of them, expressing multiple methods calls within the same loop, and presents a solution if you use this version of the notation. An alternative is to migrate to the latest UML2 standard and make use of a new feature, the interaction fragment, which explicitly addresses this area, see our interaction fragment article.
S.L.
