The UML 2.5.1 specification states about association-end ownership:
- Dot notation is used to denote association end ownership, where the dot shows that the Class at the other end of the line owns the Property whose type is the Class touched by the dot.
And it states about association-end navigability:
- Arrow notation is used to denote association end navigability. By definition, all class-owned association ends are navigable.
I can clearly see why an association end that is class-owned is navigable:
class A:
def __init__(self, b):
self.b = b # class-owned
class B:
pass
b = B()
a = A(b)
a.b # navigable
However I have more trouble figuring out how an association-end that is association-owned (so not class-owned) could be navigable?
The specification states that associations can be represented with association classes:
An AssociationClass can be seen as an Association that also has Class properties, or as a Class that also has Association properties.
So I tried to implement the association with a Python class (like in SQL where associations are often implemented with SQL association tables when the association ends are association-owned), but without much success:
class A:
pass
class B:
pass
class A_B: # association class
def __init__(self, a, b):
self.a = a # association-owned
self.b = b # association-owned
b = B()
a = A()
a_b = A_B(a, b)
a.b # not navigable (AttributeError)
The solution was to set the association link as an attribute of the class, as suggested by @qwerty_so and this article:
class A:
def link(self, b):
self.a_b = A_B(self, b) # set attribute
class B:
pass
class A_B: # association class
def __init__(self, a, b):
self.a = a # association-owned
self.b = b # association-owned
b = B()
a = A()
a.link(b)
a.a_b.b # navigable