When UML was created from various methods and notations, the most popular OO languages were Smalltalk and C++. Java was just starting to appear on the horizon. In many ways, the core concepts within UML reflect this situation by mirroring the core concepts in Smalltalk and C++ at that time. Over the last few years, additional concepts have been made more explicit in languages such as Java, Eiffel and C#. UML has needed to be extended to handle these concepts or has left it to 'convention between the user and any modeling tools and code generators'.

When UML was created from various methods and notations, the most popular OO languages were Smalltalk and C++. Java was just starting to appear on the horizon. In many ways, the core concepts within UML reflect this situation by mirroring the core concepts in Smalltalk and C++ at that time. Over the last few years, additional concepts have been made more explicit in languages such as Java, Eiffel and C#. UML has needed to be extended to handle these concepts or has left it to 'convention between the user and any modeling tools and code generators'[1]. Many of these new concepts, such as Java's package visibility, are not really that significant. However, two concepts that I have found increasingly frustrating to work with in UML are properties and services.

Properties vs attributes

In UML, an attribute is 'a named slot of a specified type in a class; each object of that class separately holds a value of the type'[1]. Attributes may be public, protected or private reflecting the access to instance variables in languages like C++. However, many developers declare all attributes of a class as private and provide appropriate public or protected accessor methods to retrieve and modify the value of those attributes. In many cases, using accessor methods means that a small change in an attribute's definition can be handled by changing the implementation of the attribute's accessor methods and changes are not needed everywhere the code uses that attribute.

Java Beans introduced a naming convention for accessor methods and called the combination of attribute and accessor methods a property of the bean. C# has syntax that makes this convention explicit.

NB: Properties as a concept have been around for along time especially in GUI oriented development environments like Visual Basic; Java Beans generalised the the concept a little further.

Properties have some interesting characteristics. A property that only has methods that retrieve its value, is a read-only property. A property may only have methods that modify its value ; a write-only property. A property may not even have an underlying attribute, its value being calculated in some way instead. Add the possibility of each accessor method being declared as protected or private (or package in Java) and the combinations increase.

A common convention when developing initial object models in Feature-Driven Development[2] and other informal object modeling techniques is to use the attribute compartment of a class to list properties rather than attributes. An entry in the attribute compartment indicates that a class has accessor methods to retrieve and/or set a value that is of importance to objects of that class. Whether or not an actual attribute is used to store the value and the exact type of that attribute are decisions deferred until later.

attribute used to represent a JavaBean style property

Figure 1: A UML attribute used as a shorthand for a JavaBean style property

This seems OK on face value and certainly works well enough when sketching models in collaborative modeling sessions. However, the code generators of many modeling tools do not recognise the convention. This forces developers to spend tedious amounts of times converting plain old attributes into properties if they want the benefit of using such tools. Also when it comes to adding more detail to the model, the convention breaks down because there is no way to indicate if the property is read only or write only or if the individual accessor methods should be public, protected or private. These constraints can severely reduce the usefulness of a modeling tool because its use is adding a burden to developers instead of helping alleviate tedious tasks.

One alternative to using the attribute compartment to list properties, is to list every accessor method in every class. This, however, badly clutters up class diagrams reducing their ability to communicate a bigger picture than raw source code.

Borland's Together ControlCenter (currently version 6) uses a different approach. It adds a custom compartment for properties to the UML class symbol below the operations compartment (a notch to the left of the class name indicates that this feature is active). This is a legal extension of UML but it only communicates to those who are aware of the meaning of the extension. Scott Ambler on his Modeling Style website (www.modelingstyle.com) recommends that, if custom compartments are used, that they be given a title describing what their contents represent. This practise would certainly help communicate better. The use of an extra compartment does not fully address the problem of specifying visibility of properties as we move from analysis into design and implementation. How would we indicate a write-only property, for example? We could list the accessor methods in the class symbol but this defeats the whole purpose of having a separate compartment for properties.

Adding a custom compartment to represent properties, optionally showing implementation details

Figure 2: Adding a custom compartment to represent properties, optionally showing implementation details

Note: Not being a Rational Rose user I do not know if Rose handles properties any better than Together. Please, let me know if it does. As far as I can tell, ArgoUML, does not address the issue either.

Services vs Operations

We have a somewhat similar situation when we look at operations. Operations in a class's public interface may represent the starting point of a collaboration providing some business service or transaction. Other public operations might be for use only within such collaborations and are not intended to be invoked directly by user or external system interface code. Other operations may provide supporting behaviour for the underlying technical architecture or infrastructure. Yet other operations are merely accessors to attributes. How in UML do we distinguish between these different kinds of operation?

In J2EE, EJB's expose a subset of their public operations to remote clients by declaring them in the EJB's remote interface. Similarly, a subset of operations supporting the creation, retrieving and destroying of EJB's are exposed in the EJB's home interface. With the growing popularity of webservices, the idea of selecting a subset of a class's public operations to expose as 'services' is becoming more and more popular. So we could define interfaces for our different types of operation and show that the class implements those interfaces. Mark Mayfield and Jill Nicola suggest a similar approach in their book, Streamlined Object Modeling[3].

Unfortunately, UML's choice of notation for interfaces is somewhat clunky and very soon leads to too many implements relationship links on a class diagram. Peter Coad's Java Design book[4] uses a much more concise notation that still remains, in my opinion, within the spirit of UML; naming supported interfaces in the operations compartment of a class symbol instead of each individual operation defined by that interface. However, I do not know of any UML tool that supports this non-standard convention.

UML Interface Notation more concise variation used in the Java Design

Figure 3: UML Interface Notation vs the more concise variation used in the Java Design and Streamlined Object Modeling books

Again, just like properties, an alternative approach is define extra compartments for the class symbol. Together ControlCenter does this for EJB's for example. However, again, this extension of UML is only useful if it is readily understood by the users of the model and it is unlikely to be portable between UML-based products.

The symbol for an EJB in Together ControlCenter

Figure 4: The symbol for an EJB in Together ControlCenter uses extra compartments to separate services from other types of operation

Levels of Detail

What is happening here is that we are wanting to see different views of a class depending on the level of detail at which we are working. And we want to be able to switch easily between those views so that we are not forced into an artificially sequential way of working. Although UML can be used at different levels, it provides little if any help in co-ordinating work done at those different levels and nothing in the work being done for 2.0 that I have seen suggests that it will in the future.

It certainly would make sense that during high-level work that we might only be interested in a properties compartment and a business services compartment in our class symbols. As we refine the model in a modeling product like Together, Rational Rose or ArgoUML, etc, it would be nice to be able to switch on more low-level compartments showing the actual attributes, accessor methods and other supporting operations. However, without properties and services being part of the core UML, each of these tools is likely to implement this sort of feature differently and the idea of a unified modeling language is diluted.

Single unified notation or a single unified abstract meta-model?

We have seen that extending UML helps accommodate some concepts that are not represented within the core UML. However, with more sets of extensions (profiles) to the core UML becoming accepted as standard extensions, we could end up with the very same problem that UML was created to solve. If we reach a point where different teams or even different sub-teams within a project can use non-overlapping subsets of UML to model the same fundamental concepts we no longer have a single notation. What we have, instead, is several 'competing' notations that are compliant with UML's underlying, abstract meta-model (model of models). Is this what we really need from a unified modeling language?

The answer depends of course. If you use UML primarily to explore and communicate analysis and high-level design with different sets of domain experts, analysts and developers then I suspect the answer is no because you could waste considerable time translating between subsets of the notation.

If you want to use UML as a comprehensive graphical programming language then maybe the answer is yes because you want UML to be a complete mechanism for expressing structure, function and state. However, if in doing so, UML diagrams become as complex to read as source code, what benefit is there in using UML over source code at that level?

Of course, the tool vendors will answer with a resounding yes, because it gives them more 'standard' features to add to the next release of their products. Perhaps that is a little cynical? However, if the new products really do help us improve our designs and speed up the creation of quality software then this is surely not a problem; but it is a big 'if'.

Conclusion

So is UML out of date? Is it out of touch with the real world? Are the various committees within the OMG, if not painting the toenails of a corpse, giving elaborate makeovers to a rapidly ageing software development artefact from the previous century? It will certainly be interesting to watch developments. In the meantime UML is as good a tool as we have and I continue to use it as best I can until something better comes along. 

References and notes

[1] Raumbaugh, Booch, Jacobson, The Unified Modeling Language Reference Manual Addison Wesley

[2] Palmer, Felsing, A Practical Guide to Feature-Driven Development, Prentice Hall

[3]Mayfield, Nicola, Abney, Streamlined Object Modeling: Patterns, Rules and Implementation, Prentice Hall

[4]Coad, Mayfield, Kern, Java Design: Building Better apps and Applets, Prentice Hall

[5] Despite formerly being a senior mentor at TogetherSoft, Stephen's opinions of TogetherSoft's Together product line are his own and not necessarily that of TogetherSoft. They in no way constitute a commitment by TogetherSoft to support or continue support the features expressed in this article in future releases within the product line.

This article was first published as CoadLetter #91 while I was an editor of that newsletter.A german translation of this article by Martin Kropp appeared in JavaSpektrum magazine in January 2003.

Follow me on Twitter...