关联端如何在 UML 中为关联所有且可导航?
How can an association end be association-owned and navigable in UML?
UML 2.5.1 specification 声明关联结束所有权:
- 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.
它说明了关联端 可导航性:
- Arrow notation is used to denote association end navigability. By definition, all class-owned association ends are navigable.
我可以清楚地看到为什么 class 拥有的关联端是可导航的:
class A:
def __init__(self, b):
self.b = b # class-owned
class B:
pass
b = B()
a = A(b)
a.b # navigable
但是,我更难以弄清楚关联拥有的关联端(因此不是 class 拥有的)如何导航?
规范指出关联可以用关联表示 classes:
An AssociationClass can be seen as an Association that also has Class properties, or as a Class that also has Association properties.
所以我尝试用 Python class 实现关联(就像在 SQL 中,关联通常用 SQL association tables 实现,当协会结束是协会所有的),但没有太大的成功:
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)
解决方案是将关联 link 设置为 class 的属性,如@qwerty_so 和 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
在您自己的回答中,您声称 A_B
是一个关联 class。这确实是一个有效的解释。
但它不是唯一的:
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)
你的pythonclassA_B
完全符合这个定义:它在关联类型之间实现了这样一个link。事实上,它提供的无非就是元组的功能(在抽象意义上)。
您模型的 classes 不一定与您的实施 classes 一对一相关。建模意味着对世界采取一种观点。 elephant and the blind persons的故事告诉我们,往往有几个有效的观点。因此,由您选择最能帮助您解决问题的那个。
补充说明:类像A_B
一样经常使用to implement many-to-many associations。当涉及三元关联时,存在类似的选择:有些人更喜欢将它们视为二元关联 class 与第三个关联 class。有些人更喜欢将其视为简单的 N 元关联。两者都可能通过在实现语言中使用 class A_B_C 来实现。
UML 2.5.1 specification 声明关联结束所有权:
- 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.
它说明了关联端 可导航性:
- Arrow notation is used to denote association end navigability. By definition, all class-owned association ends are navigable.
我可以清楚地看到为什么 class 拥有的关联端是可导航的:
class A:
def __init__(self, b):
self.b = b # class-owned
class B:
pass
b = B()
a = A(b)
a.b # navigable
但是,我更难以弄清楚关联拥有的关联端(因此不是 class 拥有的)如何导航?
规范指出关联可以用关联表示 classes:
An AssociationClass can be seen as an Association that also has Class properties, or as a Class that also has Association properties.
所以我尝试用 Python class 实现关联(就像在 SQL 中,关联通常用 SQL association tables 实现,当协会结束是协会所有的),但没有太大的成功:
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)
解决方案是将关联 link 设置为 class 的属性,如@qwerty_so 和 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
在您自己的回答中,您声称 A_B
是一个关联 class。这确实是一个有效的解释。
但它不是唯一的:
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)
你的pythonclassA_B
完全符合这个定义:它在关联类型之间实现了这样一个link。事实上,它提供的无非就是元组的功能(在抽象意义上)。
您模型的 classes 不一定与您的实施 classes 一对一相关。建模意味着对世界采取一种观点。 elephant and the blind persons的故事告诉我们,往往有几个有效的观点。因此,由您选择最能帮助您解决问题的那个。
补充说明:类像A_B
一样经常使用to implement many-to-many associations。当涉及三元关联时,存在类似的选择:有些人更喜欢将它们视为二元关联 class 与第三个关联 class。有些人更喜欢将其视为简单的 N 元关联。两者都可能通过在实现语言中使用 class A_B_C 来实现。