In the picture above class of the type implementation will at some point receive a class of type C1. Classes that implement Contact will at some point hold references to C1.
So should the diagram be more like
Your first diagram is almost correct:
Despite popular beliefs, the shared aggregation has no particular semantic defined, according to UML specifications (for more than 20 years!). It has no different meaning than a simple association. It does not imply that a reference is necessarily held.
To formally express in UML that object C1
holds a reference to the Implementation
, you must make C1
owning the association end to Implementation
. According to UML specification, this makes the object a property of the other, i.e in most OO langages holding a reference. Graphically this may be expressed with the "dot notation": a tiny dot on the end of the association on Implementation
side. Unfortunately, many low-cost tools don't support it.
Another alternative is to name the association end in the diagram, with the name of the reference stored in C1 (this is called the "role" in UML). You an easily do this in plantuml.
Another way to suggest it, is to use navigability; an open arrow on the side of the implementation would mean that You can easily go from C1
to Implementation
. It is not as accurate as the dot notation, but readers will understand what you intend to do.
You can have double dot, name both ends, and double navigation to show that each object knows the other.
Adding an artificial second association, as in you second diagram, is not to be recommended, because according to your narrative, the references in your code only implement one and the same association. Two associations should be used only if there are two different relations (e.g. for a car, having a driver and a passenger)
Well if you changed the names it might look like this:
That's from the Observer Pattern. Notice that Subject
(your Implementation
) receives an Observer
(your C1
) through attach()
. So long as that Observer
has access to Subject
, so it can call that method, it can "set it self as a member". Well, get itself added to a member collection at least.
You can see an example of code doing this on that same Wikipedia page. The C++ example listing shows ConcreteObserver
adding and removing itself in it's constructor and destructors using concreteSubject->attach(this);
and concreteSubject->detach(this);
respectively.
If you're looking at that diagram and thinking you can't really see an object attaching itself that's because a UML class diagram is the wrong kind of diagram to show this. To see this properly you should be looking at a UML sequence diagram:
You can see the pass on the first line here. Yes it used o1
rather than this
but that's just a context thing. You're looking at o1
passing itself.