UML 101

Multiplicity

One weird thing about UML is that there aren’t collection types or array
types. Basically, multiplicity and typing are totally independent
concerns, represented by the metaclasses TypedElement and
MultiplicityElement.

A typed element is a named element that has a type, and that is all
about it. Examples of typed elements are value specifications,
properties, parameters, pins and variables.

A multiplicity element, on the other hand, is an element that when
instantiated potentially admits a collection of values. An optionally
defined lower bound value (defaults to 1) can determine the minimum
number of instances expected. Whether multiple values are in fact
admitted will depend on the upper bound of the multiplicity element,
which defaults to 1 (no multiple values allowed), but can be set to any
positive integer, or infinity. A multiplicity element that can actually
be multivalued can also be characterized regarding ordering (whether
values can be accessed by position) and uniqueness (whether values can
be repeated).

Some kinds of elements are both typed and support multiplicity (such as
properties, parameters, pins and variables), however a few are one or
the other (let’s ignore those in this discussion).

Mapping UML multiplicities to Java

To try to illustrate all that was said above, let’s see a few examples
of Java variable declarations and the equivalent declaration in UML
(using TextUML syntax):

declaration

Java

TextUML

single-valued

Client c

c : Client

multi-valued

Collection c

c : Client[*] {unique}

ordered

List c

c : Client[*] {ordered}

unique

Set c

c : Client[*] {unique}

optional

Optional c (Java 8)

c : Client[0, 1]

There are few interesting differences though:

in UML, it is the typed element itself that defines multiplicity,
and not the type

c:Client, c:Client[1] and c:Client[1,1] are all equivalent

c:Client[*], c:Client[1,*] are equivalent

if a value is optional, the lower bound must be specified to be 0
(example: c:Client[0,1]). There is no Java equivalent for that (update: Java 8 includes support for Optional).

unique and unordered are the default in UML (you can use the
modifiers ‘nonunique’ and ‘ordered’ to override the defaults)

There are some implications related to assignment when the source and
destination are multiplicity elements:

the upper bound of the destination must be the same or greater than
the upper bound of the source, or a type mismatch will ensue

what happens if source and destination differ on ordering or
unicity? The UML spec does not sem to cover that (let us
know if
you think otherwise). In TextUML, any required transformations are
performed automatically behind the scenes. For example: if the
source is non-unique and the destination is unique, duplicates will
be silently suppressed, or if the source is unordered and the
destination is ordered, an arbitrary order will be defined.

Profiles and Stereotypes

Profiles and stereotypes form a lightweight mechanism for extending the
UML metamodel.

A stereotype allows you to tag elements in your model so they can be
interpreted differently from ordinary model elements, much like
annotations work in languages such as C# and Java. These tags can then
be used to drive code generation, for example, so for every class marked
as “persistent”, appropriate persistence code should be generated.

A profile is a special kind of package intended to contain stereotype
declarations that extend UML to cover some specific domain or platform.

Let’s see how to declare and use profiles and stereotypes with the help
of the TextUML Toolkit.

In other words, a stereotype can be declared as applicable to one or
more metaclasses (i.e. types of elements in a UML model), and a
stereotype can optionally declare properties (more on properties later)
. For instance, a class could be tagged with the <<persistent>>
stereotype:

Any UML element can be affected by stereotypes, but stereotypes are
declared as targetting (potentially multiple) specific element types.
For instance, the UML specification has an example of a profile for
Enterprise JavaBeans that defines a <<Session>> stereotype for
session beans. The<<Session>> stereotype declares a property that
allows modelers to define whether the session bean component is stateful
or stateless.

Applying a stereotype

Now that we know how to declare stereotypes, lets see how to use them.
First of all, you must apply the profile defining the stereotypes to the
model declaring elements you want to apply stereotypes to:

modelbank;applybusiness_apps;/*othermodelelementshere*/end.

You can then attach stereotypes defined in the applied profile to the
suitable model elements in your model:

In the example above, we applied the <<persistent>> stereotype to
the Bank class, and the <<transactional>> stereotype to the
withdraw, deposit and transfer operations. In order to have access to
these stereotypes, we had to apply the “business_apps” profile to our
model.

Conclusion

In this article, we saw how to declare stereotypes and apply them to
elements in UML models. We learned that a stereotype must explicitly
declare the metaclasses they are applicable to, and that optionally
stereotypes might declare properties. Finally, we saw that before a
stereotype can be used in a model, the profile declaring the stereotype
must be applied to the model.

Templates

One of the least known and understood concepts of UML is templates.
Section 17.5 on version 2.1.1 of the UML specification covers the
Templates package in 31 pages. What follows is an attempt at providing a
summary of the mechanism in a way that is easy to understand without
actually omitting any important details.

A simple example

The following example in TextUML should be easy to understand for any
developer familiar with C++ parametrized types or Java generics:

Class ‘Bar’ is a template class, whose template signature contains a
single parameter: ‘T’. The type of the property ‘prop1′ is defined as
the template parameter ‘T’. Class ‘Fred’ declares ’someOp1′, an
operation that takes a parameter whose type is a binding of the template
class ‘Bar’. ‘Bar’’s template parameter ‘T’ is bound to the class ‘Foo’.
Implicitly, the type of ‘Fred.attr1′ when expanded against Foo should
look something like:

Note that the expanded class has actually no name, but I am calling it
‘BarOfZoo’ for pedagogical reasons.

Looking closer at the abstractions

TemplateableElements - abstract super-class for elements that
can be declared as templates, or that can bind other templates to a
set of parameters. Four kinds of elements can be declared as
templates in UML 2.*: Classifier, Operation, Package and
StringExpression, and thus only those metaclasses specialize
TemplateableElement*.

ParameterableElements - abstract class that is specialized by
any type of element that can be used as parameters to templates.

TemplateSignature - a template signature is owned by a template
element and contains the set of parameters declared by a template
element.

TemplateBinding - a template binding represents the
“instantiation” of a template in the form of a directed relationship
between a template signature and a a bound element, another
templateable element. In addition to tying the template to the bound
element through the template’s signature, the template binding
contains a set of template parameter substitutions. Which takes us
to the next abstraction…

TemplateParameterSubstitution - a template parameter
substitution is created for every template parameter declared by a
template signature. It binds an open parameter to an actual
parameter, which is a ParameterableElement.

Would you like to play with templates in UML? There is some support for
templates in the TextUML Toolkit since M2, but it is, to put it mildly,
not fully baked.