Search code examples
javatemplatesdependenciesumlclass-diagram

How to represent dependency injection with generics in UML class diagram?


I'm having trouble representing the following piece of code in a UML class diagram:

public class Test {
    // something
}

public class Bar<T> {
    private T item;

    public Bar(T item) {
        this.item = item;
    }

    // something
}

public class Foo<T> {
    private Bar<T> bar;

    public Foo(Bar<T> bar) {
        this.bar = bar;
    }

    // something
}

public class Caller {
    private Test item;
    private Foo<Test> foo;
    private Bar<Test> bar;

    public Caller() {
        item = new Test();
        bar = new Bar<Test>(item);
        foo = new Foo<Test>(bar);
    }

    // something
}

As of now, I thought to represent it this way:

This Way

Since I know you can't directly bind an association, but you need a bound class first. I don't know if it's correct and, if it is, wouldn't this result in a much more complex diagram when there are more classes?


Solution

  • Complete your diagram?

    The assumption that an association cannot be bound seems unfounded. According to the UML specs, a classifier can be templated, and a template can be bound. This is straightforward for classes. Associations are also classifiers, and I found no evidence that the general rules don't apply to them.

    You may therefore very well complete your diagram if you think it increases readability. Use the same notation: add an association between Foo_Test and Bar_Test, as well as a «bind» arrow from that association to the template association (btw. it may seem weird to link with an arrow two lines, but even if it’s rate, it’s legit; generalization are also possible for associations, see here).

    How to use templates in UML

    Templates are an additional level of abstraction. Models that stay at the same level of abstractions tend to be easier to understand. It is therefore preferable to isolate relationships between template classes (bottom of your diagram) in a separate diagram focused on the “meta” level.

    It’s then not an issue to show a set of bound classes and highlight one of the bindings with a template class: the reader can refer to the other diagram easily. But when combined with bindings, teplates quickly lead to very complex diagrams that are difficult to understand.

    You may instead prefer to keep diagram as simple as possible.

    But first, let’s clarify the «bind» relation between a template and the bound class. It is neither an inheritance nor a realization, and has still some mysteries:

    A Classifier that is parameterized using a RedefinableTemplateSignature is called a template Classifier, while a Classifier with one or more TemplateBindings is called a bound Classifier.

    (...) the details of how the contents are merged into a bound element are left open. In the case of Classifier the semantics are equivalent to inserting an anonymous general bound Classifier representing the intermediate result for each binding, and specializing all these intermediate results by the bound Classifier.

    (...) A bound Classifier may have contents in addition to those resulting from its bindings.

    So, the way the template work is not fully defined by UML but you can assume that a bound class gets all the content "bound" (instead of "inherited", my own analogy) from the templates.

    Simplify your diagram?

    With this in mind you can use a notational shortcut: The notation allows you to show anonymous bound class, using directly the binding in the class. The binding arrow are then implicit. The dependency to Test moreover also becomes implicit, simplifying the diagram.

    enter image description here

    Ideally, the bottom part would be in a separate diagram. But if you keep it,, you may avoid the association between Bar and Test (since it is deduced from a item: T in the template), unless you think it is important.