templateslanguage-lawyerumlclass-diagram

How to model a given implementation of a map<K,V> in UML?


Today I commented this answer showing a possible implementation of a map in the diagram below, saying it is wrong.

In that answer the diagram is :

enter image description here

For me the aggregation between the template classes Map and Map.Entry is invalid because in the §7.3.3.1 Templates page 24 of formal/2017-12-05 it is written :

A template cannot be used in the same manner as a non-template Element of the same kind (e.g., a template Class cannot be used as the type of a TypedElement). The template Element can only be used to generate bound Elements or as part of the specification of another template (e.g., a template Class may specialize another template Class).

but the template class Map.Entry is used to type the unnamed property of Map.

So in a comment I proposed the following diagram based on the OP's one : enter image description here

where the type of the (still) unnamed property of Map is Map.AnEntry being a completely bound element of Map.Entry. I also renamed the ParameterElement by doubling their first letter to have the bindings KKey -> Key and VValue -> Value rather than the less clear Key -> Key and Value -> Value.

In the bindings KKey -> Key and VValue -> Value, Key and Values refer to the ParameterElement of Map, and that is where I may have a doubt.

I mean typically in C++ in template <typename Key, typename Value> class Map {...} there is no problem to use MapEntry<Key, Value>, but in the UML model even the class Map.xxx are nested in Map it's not the same thing, if I can say there is no scope story allowing Key and Value to be know by Map.AnEntry for its binding.

So, is my model legal, else what change can be done staying in the same spirit for the implementation of the map ?


Solution

  • The templates in UML are unfortunately poorly defined, as they left many details unspecified.

    Indeed, formally, the first model should be wrong because of the clause you have pointed out. Moreover, the template parameter names are by coincidence the same, but nothing in the specs guarantees they refer to the same parameters. This is only human interpretation, but in reality we should read it as if it would be completely different parameters.

    Your alternative is unfortunately formally wrong as well. You skilfully avoid the (formal) trap of the first diagram. But Map.anEntry is a bound element, and I have not seen in the specs the possibility to reuse the parameter of the template that was bound, and I think the bounding must use substitution with a real type.

    In fact, most modern generic constructs, be it C++ templates or Java or Swift generics, cannot be easily modelled in UML, if following strictly the specs. For example, a simple Collection of T cannot be modelled to show the templates collection, and the items of type T, whereas modern development uses such techniques extensively. The only way round is then to use language specific understanding of the template and use it in UML as if the implementation language semantics would apply (this is the case of the first diagram), or visual workarounds, in both case with the risk of generating formally wrong models and misunderstandings of the readers. See also this other answer:

    (My own opinion, is that generics in programming language will be the death sentence to UML, if it doesn't evolve, as it becomes increasingly difficult to model generic design, leading to diagrams that are more difficult to understand than in the implementation language)