Как конец ассоциации может принадлежать ассоциации и быть доступным для навигации в UML?

Спецификация UML 2.5.1 гласит о владении на конце ассоциации:

  • Обозначение через точку используется для обозначения принадлежности конца ассоциации, где точка показывает, что класс на другом конце линии владеет свойством, тип которого является классом, затронутым точкой.

И в нем говорится о навигации в конце ассоциации:

  • Обозначение стрелки используется для обозначения возможности навигации в конце ассоциации. По определению все концы ассоциации, принадлежащие классу, доступны для навигации.

Я ясно понимаю, почему конец ассоциации, принадлежащий классу, доступен для навигации:

class A:
    def __init__(self, b):
        self.b = b  # class-owned

class B:
    pass

b = B()
a = A(b)
a.b  # navigable

Однако у меня больше проблем с выяснением того, как можно перемещаться по концу ассоциации, принадлежащему ассоциации (то есть не принадлежащему классу)?

В спецификации указано, что ассоциации могут быть представлены классами ассоциаций:

AssociationClass можно рассматривать как ассоциацию, которая также имеет свойства класса, или как класс, который также имеет свойства ассоциации.

Поэтому я попытался реализовать ассоциацию с классом Python (как в SQL, где ассоциации часто реализуются с помощью таблиц ассоциаций SQL , когда концы ассоциации принадлежат ассоциации), но без особого успеха:

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)

Потому что ассоциация привязана к любому концу, а не висит в воздухе.

qwerty_so 12.12.2020 01:04

@qwerty_so Вы имеете в виду, что если конец ассоциации не принадлежит классу, то сама ассоциация принадлежит классу? Другими словами, всегда есть элемент, принадлежащий классу.

Géry Ogam 12.12.2020 01:14

Ассоциация представляет собой связь между 2 или более классами. Роли представляют собой свойства классов, связанных через ассоциацию.

qwerty_so 12.12.2020 01:18

Ваш A_B не является ассоциацией. Это класс, который имеет ассоциации с A и B.

qwerty_so 12.12.2020 01:23

@qwerty_so Согласно спецификации UML, это класс ассоциации и, следовательно, ассоциация, поскольку она специализируется на ней: «Класс ассоциации можно рассматривать как ассоциацию, которая также имеет свойства класса, или как класс, который также имеет свойства ассоциации». Так что я не вижу ничего плохого в представлении ассоциаций с классами Python. В SQL люди делают то же самое, представляя ассоциации с таблицами ассоциаций SQL , когда концы ассоциации принадлежат ассоциации.

Géry Ogam 12.12.2020 01:45

@qwerty_so Я только что опубликовал решение ниже. Спасибо за вашу помощь!

Géry Ogam 12.12.2020 02:07
В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Принцип подстановки Лискова
Принцип подстановки Лискова
Принцип подстановки Лискова (LSP) - это принцип объектно-ориентированного программирования, который гласит, что объекты суперкласса должны иметь...
3
6
173
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Решение состояло в том, чтобы установить ссылку ассоциации в качестве атрибута класса, как это было предложено @qwerty_so и этой статье:

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

Я взял на себя смелость разместить ваш комментарий в ответе, где он должен быть.

qwerty_so 12.12.2020 11:29

@qwerty_so Спасибо, я переместил это в вопрос, потому что там это имеет больше смысла.

Géry Ogam 12.12.2020 16:24

Моя причина заключалась в том, что ответы должны фактически отвечать на вопрос (что и сделала вставка). Ответ только по ссылке недействителен!

qwerty_so 12.12.2020 19:43

@qwerty_so Цитата из спецификации UML отвечает на ваш вопрос о природе класса Python A_B: «Ваш A_B не является ассоциацией. Это класс, который имеет ассоциации с A и B». Это ассоциация (и даже без класса ассоциации UML, см. ответ Кристофа). Но это не отвечает на мой вопрос о том, как реализовать навигацию по концу ассоциации, принадлежащему ассоциации. Ответ состоял в том, чтобы сделать A_B атрибутом A в качестве ссылки, и вы предложили: «Потому что ассоциация привязана к обоим концам, а не висит в воздухе».

Géry Ogam 12.12.2020 21:52

Не в этом дело. Ответ только по ссылке недействителен. Теперь я замечаю разницу в коде, но это не очевидно. Поэтому, пожалуйста, обобщите реальное решение в своем ответе, а не просто добавляйте ссылку, которая может исчезнуть через год (или меньше).

qwerty_so 13.12.2020 00:29

@qwerty_so Это уже то, что я сделал: «Решением было установить ссылку ассоциации как атрибут класса»,

Géry Ogam 13.12.2020 00:32

Ну тогда оставь как есть. Для меня это не очень хороший ответ. Хорошего дня. (И, возможно, сравните это с объяснением Кристофа.)

qwerty_so 13.12.2020 00:34

В своем собственном ответе вы утверждаете, что A_B - это класс ассоциации. Это действительно верная интерпретация.

Но не единственный:

Ассоциация объявляет, что могут быть связи между экземплярами, типы которых соответствуют или реализуют связанные типы. Ссылка — это кортеж с одним значением для каждого memberEnd ассоциации, где каждое значение — это экземпляр, тип которого соответствует типу на конце или реализует его. (раздел 11.5.3.1)

Ваш класс Python A_B полностью соответствует этому определению: он реализует такую ​​связь между связанными типами. На самом деле он предоставляет не что иное, как функциональность кортежа (в абстрактном смысле).

Классы вашей модели не обязательно связаны один к одному с вашими классами реализации. Моделирование означает принять точку зрения на мир. История слона и слепых говорит нам, что часто есть несколько действительных точек зрения. Таким образом, вы должны выбрать тот, который поможет вам лучше всего решить вашу проблему.

Дополнительное замечание: такие классы, как A_B, часто используются для реализации ассоциаций «многие ко многим». Аналогичный выбор существует, когда задействованы тройные ассоциации: некоторые предпочитают рассматривать их как класс бинарных ассоциаций, имеющий ассоциацию с третьим классом. Некоторые предпочитают рассматривать его как простую N-арную ассоциацию. Оба, вероятно, будут реализованы с использованием класса A_B_C на языке реализации.

Вы имеете в виду, что мне даже не нужно было вводить более точное (специализированное) понятие класса ассоциации, я мог просто назвать его ассоциацией (например, 3 можно просто назвать числом, а не целым числом)? Или вы имеете в виду, что его также можно интерпретировать как не класс ассоциации?

Géry Ogam 12.12.2020 17:05

@Maggyero второй: ваша модель имеет два класса A, B и связь между ними. Классы Python A и B реализуют классы A и B UML, а класс A_B Python реализует ассоциацию UML.

Christophe 12.12.2020 17:17

Хорошо. Класс A_B был бы необходим как класс ассоциации только в том случае, если бы он имел дополнительные свойства (помимо участников a и b), что здесь не так, поэтому возможны обе интерпретации?

Géry Ogam 12.12.2020 18:03

@Магьеро Точно!

Christophe 12.12.2020 18:04

Другие вопросы по теме