假设您要绘制一个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..*) 行和从Setto 的Node另一Set行Edge。但是现在我说每个集合都可以有Nodes 和Edges 的任意组合,这是不正确的。并且在图表上放置两个Set元素(有两条对应的 Composed-Of(1:1) 线)也无济于事,因为它们是同一个对象。
所以我想:嗯,也许 UML 想让我更像 C++/Java-ey。在 UML 中不可能使用模板化Set<Node>,但我可以创建子类:和.Set<Edge>NodeSetEdgeSet
最后我考虑了一个对象图,但那是不对的。我说的是Set类,而不是个别Set实例。
有更好的答案吗?还是我已经找到了“最不坏”的那个?
之后
正如我最初所说的那样,Marc W和Pete Kirkham的回答非常适合这个问题。问题是我试图对我的实际问题使用一个简单的类比,因为我无法揭示存在的问题。我真的只是在了解如何拥有两个具有不同关系但行为相同并具有相同属性(尽管不是属性值)的同一类。
让我们用一些不同的模型再试一次:an ActiveDirectory、aFirewall和 two Routers。一台路由器(LAN 一台)引用了ActiveDirectory和Firewall; 另一个(广域网)引用了Firewall一些公共服务器(我们将在此图中忽略它们)。完全可以想象,两个Routers 的品牌、型号等都相同。它们会有不同的序列号(对象不同),但它们肯定都是Routers。然而,要将两者都放在类图上,我必须将其子类Router化为LANRouterand WANRouter。类比 Marc W 的解决方案是直接连接Firewalland ActiveDirectory,留下实现 (Router) 到类来确定。但是,如果要使用 UML 来实际构建系统,则抽象必须泄漏。