3

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)
Géry Ogam
  • 6,336
  • 4
  • 38
  • 67
  • 1
    Because the association is _attached_ to either ends and not hanging in thin air. – qwerty_so Dec 12 '20 at 00:04
  • @qwerty_so Do you mean that if the association-end is not class-owned then the association itself is class-owned? In other words there is always an element to be class-owned. – Géry Ogam Dec 12 '20 at 00:14
  • The assocation represents the connection between 2 or more classes. Roles represent properties of the classes connected through the association. – qwerty_so Dec 12 '20 at 00:18
  • Your A_B is not an association. It's a class that has associations to A and B. – qwerty_so Dec 12 '20 at 00:23
  • @qwerty_so According to the UML specification, it is an association class, and therefore an association since it specializes it: "An AssociationClass can be seen as an Association that also has Class properties, or as a Class that also has Association properties." So I see nothing wrong with representing associations with Python classes. In SQL people do the same by representing associations with SQL [association tables](https://en.wikipedia.org/wiki/Associative_entity) when the association ends are association-owned. – Géry Ogam Dec 12 '20 at 00:45
  • @qwerty_so I have just posted the solution below. Thanks for your help! – Géry Ogam Dec 12 '20 at 01:07

2 Answers2

3

In your own answer you claim that A_B is an association class. This is indeed a valid interpretation.

But it's not the only one:

An Association declares that there can be links between instances whose types conform to or implement the associated types. A link is a tuple with one value for each memberEnd of the Association, where each value is an instance whose type conforms to or implements the type at the end. (section 11.5.3.1)

Your python class A_B fully meets this definition: it implements such a link between the associated types. In fact, it provides nothing more an nothing less than the functionality of a tuple (in the abstract sense).

The classes of your model are not necessarily related one to one to your implementation classes. Modelling means to take a viewpoint on the world. The story of the elephant and the blind persons tells us, there are often several valid view points. So, up to you to chose the one which helps you best to solve your problem.

Additional remark: Classes like A_B are frequently used to implement many-to-many associations. A similar choice exists when ternary associations are involved: some prefer to see them as a binary association class having an association with a third class. Some prefer to see it as a simple N-ary association. Both would probably be implemented with using an class A_B_C in the implementeation language.

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • Do you mean that I didn’t even have to introduce the more precise (specialized) *association class* concept, I could simply have called it an *association* (like 3 can simply be called a number instead of an integer)? Or do you mean that it can also be interpreted as *not* an association class? – Géry Ogam Dec 12 '20 at 16:05
  • 1
    @Maggyero the second: Your model has two classes A, B and an association between them. The python classes A and B implement the UML classes A and B, and the python class A_B implements the UML association. – Christophe Dec 12 '20 at 16:17
  • 1
    Okay. The class A_B would be necessary an association class only if it had extra properties (besides the participants a and b), which is not the case here so both interpretations are possible? – Géry Ogam Dec 12 '20 at 17:03
  • @Maggyero Exactly ! – Christophe Dec 12 '20 at 17:04
1

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
Géry Ogam
  • 6,336
  • 4
  • 38
  • 67
  • I took the freedom to place your comment in the answer where it belongs. – qwerty_so Dec 12 '20 at 10:29
  • @qwerty_so Thanks, I have moved it to the question because it makes more sense there. – Géry Ogam Dec 12 '20 at 15:24
  • My reason was that answers should actually answer the question (which the insert did). A link-only answer is invalid! – qwerty_so Dec 12 '20 at 18:43
  • @qwerty_so The quotation from the UML specification answers your question on the *nature* of the Python class `A_B`: "Your A_B is not an association. It's a class that has associations to A and B." It *is* an association (and even without requiring an UML association class, cf. Christophe’s answer). But it does not address my question which was about how to implement the navigability of an association-end that is association-owned. The answer was to make `A_B` an attribute of `A` as the link and you suggested: "Because the association is attached to either ends and not hanging in thin air." – Géry Ogam Dec 12 '20 at 20:52
  • That's not the point. A link-only answer is not valid. I now notice the difference in the code, but that's not obvious. So please, summarize the real solution in your answer and do not just add a link which might be gone in a year (or less). – qwerty_so Dec 12 '20 at 23:29
  • @qwerty_so That is already what I did: "The solution was to set the association link as an attribute of the class," – Géry Ogam Dec 12 '20 at 23:32
  • Well, then leave it as it is. To me that's then not a good answer. Have a nice day. (And maybe compare that to Christophe's explanation.) – qwerty_so Dec 12 '20 at 23:34