其中';UML中类和对象之间的中间地带是什么?

其中';UML中类和对象之间的中间地带是什么?,uml,class-diagram,object-diagram,Uml,Class Diagram,Object Diagram,假设您想要绘制一个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 ...

假设您想要绘制一个
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
类。和
节点
类。和一个
Edge
类。和
集合
类。好的现在,我将从
Map
Set
绘制一条由(1:2)组成的线——每个
@节点和
@边各一条。然后一个从
Set
Node
有许多(1:0..*)行,另一个从
Set
Edge
。但是现在我要说的是,每个集合可以有
节点
s和
s的任意组合,这是不正确的。在图上放置两个
Set
元素(由两个对应的(1:1)行组成)没有帮助,因为它们是同一个对象

所以我想:也许UML希望我更像C++/JavaEY。模板化的
Set
Set
在UML中是不可能的,但我可以创建子类:
NodeSet
EdgeSet

最后我考虑了一个对象图,但那是不对的。我说的是
Set
类,而不是单个
Set
实例

有更好的答案吗?还是我已经找到了“最不坏”的

以后

当我第一次用词回答这个问题时,答案是非常棒的。问题是,我试图用一个简单的类比来描述我真正的问题,因为我无法揭示问题的存在。我只是想了解如何让同一个类中的两个具有不同关系,但行为相同且具有相同属性(但不是属性值)的部分


让我们用一些不同的型号再试一次:一个
ActiveDirectory
,一个
防火墙
,和两个
路由器
s。一个路由器(LAN路由器)引用了
ActiveDirectory
防火墙
;另一个(WAN)引用了
防火墙
和一些公共服务器(在本图中我们将忽略它们)。完全可以想象,这两个
路由器
的品牌、型号和c都是相同的。它们将有不同的序列号(对象不同),但它们肯定都是
Router
s。然而,要将两者都放在类图上,我必须将
Router
分为
LANRouter
WANRouter
。Marc W的解决方案类似于直接连接
防火墙
ActiveDirectory
,将实现(
路由器
)留给类来确定。但是,如果要使用UML实际构建系统,则抽象必须泄漏。

不要从
映射到
设置
。在本例中,
Set
只是Ruby提供给您的一个数据结构,其中包含真正重要的对象。无论是
集合
哈希映射
数组
,等等,都是特定于实现的,对于UML来说并不重要。只需从
Map
Node
和从
Map
Edge
制作一条由(1:0..*)组成的线。毕竟,在英语中,你的
地图实际上是由节点和边组成的,对吗?在图表中包含
Map
的原因是,实际上是您创建了类


关于对象图,您是对的:在这种情况下没有必要这样做。与您建议的模板语法相同。

如果您是对域建模,而不是对实现建模,UML会为关系提供原型。在本例中,您将节点和边标记为{unordered},这与包或集合有关,而{unique}将其缩小为集合。我看不到对节点或边类型的任何限制,因此如果没有,请不要尝试添加它:

class Map
  +nodes : { unordered, unique } object[0..*]
  +edges : { unordered, unique } object[0..*]
  +minimum_spanning_tree(mst_algorithm:callable)
一个好的代码生成器/逆向工程工具可以将{无序的、唯一的}UML集合映射到源代码中的集合

如果该信息对您有用,您可能希望在域模型中使映射成为参数化类型。但是,由于实现中没有使用这些信息,因此很难看出要点,建模的目标始终是使事情尽可能简单而不失去实用性


如果您想记录某个特定类是使用集合实现的,那么可以通过关联来实现。C++和java允许声明集合中元素的类型,这些映射映射到UML中的参数类型。AFAIK Ruby没有实现此类类型限制的机制,因此要记录映射的Ruby实现,只记录实现中的内容-映射有两个要设置的关联,并且不限制集中的内容。(您可能希望将其记录为一个不变的约束,然后进行单元测试,而不是类型约束,但同样,如果您想要限制性的静态类型检查,就有点难以理解为什么要在Ruby中工作)

如果我试图为实现绘制图表,该怎么办?比如说,如果我的组织做了大量的外包,并希望为CYA目的提供各种文档,{unordered}和{unique}是约束,而不是原型。但答案很好,+1没错。但您可以做的是定义关联端的属性是unique=true和isOrdered=false。这表示关联不包含重复的元素,并且元素没有顺序。在概念层面上,这是一种表示建议中的“设置行为”点的方法:将集合类从类图中删除。您的“稍后”部分使您的问题更加清晰,同时也更加混乱。:)请澄清