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.
Declaring a stereotype
To declare a stereotype in TextUML, one uses the following syntax:
profile <profile-name>; stereotype <stereotype-name> extends <metaclass-1 [,...metaclass-n]...] [<property-1>; [... property-n;]...] end; end.
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 classes could be tagged with the <<persistent>> stereotype:
profile business_apps; import uml; stereotype persistent extends Class end; end.
Or operations could be marked as <<transactional>>, meaning that a transaction will be started whenever the operation starts executing, and finished when its execution ends:
profile business_apps; import uml; stereotype transactional extends Operation end; end.
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.
profile EJB; enumeration StateKind STATELESS, STATEFUL end; stereotype Bean extends uml::Component end; stereotype Session specializes Bean property kind : StateKind; end; stereotype Entity specializes Bean end; end.
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:
model bank; apply business_apps; /* other model elements here */ end.
You can then attach stereotypes defined in the applied profile to the suitable model elements in your model:
model bank; apply business_apps; [persistent] class Account attribute accountNumber : base::String; attribute balance : base::Real; attribute changes : AccountChange[0,*]; [transactional] operation withdraw(amount : Real); [transactional] operation deposit(amount : Real); operation balance() : Real; [transactional] operation transfer(other : Account, amount : Real); end; end.
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.
In this post/article on UML basics using TextUML, 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.