假设您要绘制一个Map
类(数学类,而不是制图类)。在 Ruby 中,你可能有类似的东西:
class Map
attr_accessor :nodes, :edges
def initialize
@nodes = Set.new
@edges = Set.new
end
def minimum_spanning_tree(&mst_algorithm)
mst_algorithm.call(@nodes, @edges)
end
...
end
当我开始绘制图表时,我的想法如下:
让我们尝试一个类图,因为我们正在讨论类。我会创建一个Map
类。和一Node
堂课。和一Edge
堂课。和一Set
堂课。美好的。现在我将绘制一条 Composed-Of(1:2) 线,从Map
到Set
—— 每个@nodes
和@edges
。然后是从 to 的 has-many(1:0..*) 行和从Set
to 的Node
另一Set
行Edge
。但是现在我说每个集合都可以有Node
s 和Edge
s 的任意组合,这是不正确的。并且在图表上放置两个Set
元素(有两条对应的 Composed-Of(1:1) 线)也无济于事,因为它们是同一个对象。
所以我想:嗯,也许 UML 想让我更像 C++/Java-ey。在 UML 中不可能使用模板化Set<Node>
,但我可以创建子类:和.Set<Edge>
NodeSet
EdgeSet
最后我考虑了一个对象图,但那是不对的。我说的是Set
类,而不是个别Set
实例。
有更好的答案吗?还是我已经找到了“最不坏”的那个?
之后
正如我最初所说的那样,Marc W和Pete Kirkham的回答非常适合这个问题。问题是我试图对我的实际问题使用一个简单的类比,因为我无法揭示存在的问题。我真的只是在了解如何拥有两个具有不同关系但行为相同并具有相同属性(尽管不是属性值)的同一类。
让我们用一些不同的模型再试一次:an ActiveDirectory
、aFirewall
和 two Router
s。一台路由器(LAN 一台)引用了ActiveDirectory
和Firewall
; 另一个(广域网)引用了Firewall
一些公共服务器(我们将在此图中忽略它们)。完全可以想象,两个Router
s 的品牌、型号等都相同。它们会有不同的序列号(对象不同),但它们肯定都是Router
s。然而,要将两者都放在类图上,我必须将其子类Router
化为LANRouter
and WANRouter
。类比 Marc W 的解决方案是直接连接Firewall
and ActiveDirectory
,留下实现 (Router
) 到类来确定。但是,如果要使用 UML 来实际构建系统,则抽象必须泄漏。