UML 关系 - 虚线与实线

Posted

技术标签:

【中文标题】UML 关系 - 虚线与实线【英文标题】:UML relationships - dashed line vs solid line 【发布时间】:2015-01-14 23:12:06 【问题描述】:

这两种关系有什么区别?

编辑:另外,如果您可以提供一个简单的代码示例来说明差异,那将非常有帮助!

【问题讨论】:

【参考方案1】:

我试图给出这两种线条的简单示例。

在第一张图中,实线表示关联:

如果类是在 Java 中声明的,这就像 ClassA 存储对 ClassB 的引用作为属性(它可以传递给构造函数、创建等)。因此,您可能会看到如下内容:

public class ClassA 
    ClassB theClassB = ...
    ...

在第二张图中,它显示了一个依赖关系:

依赖比关联弱得多。引用 UML Distilled:

对于类,存在依赖关系的原因有很多:一个类向另一个类发送消息;一类有另一类作为其数据的一部分;一 类提到另一个作为操作的参数。 [...]您使用依赖项 每当您想展示一个元素的变化可能如何改变其他元素时。

同样,使用 Java,有几个例子:ClassB 类型的参数被传递给方法,或者方法声明了 ClassB 类型的局部变量:

public class ClassA 
    ...
    public void someMethod(ClassB arg1) ...
    ...
    public void someOtherMethod() 
        ClassB localReferenceToClassB = ...
    
    ...

ClassA 可以在没有关联的情况下依赖ClassB 的其他方式(不是详尽的列表):

ClassB 有一个 ClassA 调用的静态方法 ClassA 捕获 ClassB 类型的异常 每当ClassB被修改时,ClassA也必须被修改(例如,某些逻辑是共享的)

【讨论】:

【参考方案2】:

This webpage 说得够多了 以下文字来自它,但应该足以理解其中的区别。

所以基本上实线是一个关联,虚线/点线是一个依赖。

关联也可以是单向的,其中一个类知道 另一个类和关系,但另一个类没有。 这种关联需要一个开放的箭头来指向类 是已知的,并且只有已知的类可以有一个角色名称和 多样性。在示例中,Customer 类知道任何 购买的产品数量,但 Product 类一无所知 任何客户。多重性“0..*”表示零个或多个。

依赖是两个类之间的弱关系,是 用虚线表示。在示例中,存在依赖项 Point 和 LineSegment 之间,因为 LineSegment 的 draw() 操作 使用 Point 类。它表示 LineSegment 必须知道 点,即使它没有该类型的属性。这个例子也 说明如何使用类图来关注什么是 在上下文中很重要,因为您通常不想显示此类 所有类操作的详细依赖关系。

由于我的声誉只有 8,我无法放置图像本身,但仍然可以在我开头提到的网页上找到它们。

[编辑]

我这里没有代码示例,但我个人会如何解释它就像一辆车和一扇门一样简单。

如果汽车有一扇(或更多)门,那它就是一辆车

Car --- has a --> Door

但是当你有一扇门可以打开门类将有一个类似的功能

public void openDoor()
this.open();

要使用上面的函数,汽车必须创建一个门实例

Class Car()
Door door1 = new Door();

door1.open();

这样你就创建了一个依赖。

所以实线只是将一个对象(1)指向另一个对象(2),但是当您开始使用对象(1)时,它就变成了一个依赖项。

【讨论】:

不幸的是,我仍然无法区分。你认为你可以提供简单的代码示例来说明这两种关系之间的区别吗? 我不认为上面的代码示例是正确的。没有直接的 UML 到代码转换,但如果有的话,关联通常会转换为相反类型的属性。因此,具有 SteeringWheel 类型的属性或 List 类型的属性的 Car 可以是关联的翻译。依赖关系通常是较弱的关系。类似于具有 DriveTo(Location destination) 操作的汽车。位置是已知的并且被 Car 使用,因此存在对位置的依赖。 我相信它更具体一些。您在这里描述了两个关联,“汽车有门”和“汽车的门可以打开”。它们是被动的,实际上并不使用 Door 的对象。对于依赖项,您主动使用 Door 的对象:如果 Door 具有对象“Width”和“Max_aperture_angle”,并且 Car 具有使用这两个对象的方法“Max_car_width”,那么您就有了依赖项。【参考方案3】:

你的问题给了我一个自我学习的好机会,这就是我发现的——

关联:其他类型的所有权(例如,“A”拥有“B”)

//@assoc  The Player(A) has some Dice(B)
class Player 
    Dice myDice;

依赖性:使用另一种类型(例如,“C”使用“D”)

//@dep    The Player(C) uses some Dice(D) when playing a game
class Player 
    rollYahtzee(Dice someDice);

这是我找到的一个清晰的参考 - Association vs. Dependency

【讨论】:

【参考方案4】:

好的,既然你没有接受第一个答案;让我试试。

箭头 1:正常关联

UML 有不同类型的线和箭头。上面是简单的关联箭头,这意味着一个类可以链接到另一个类。下面我将用代码示例解释每种类型。

在第一个示例中,您可以看到没有真正指定谁知道谁(谁是关系的所有者)。动物可以认识人类,而人类可以认识动物。它没有具体说明,因此对程序员没有真正的帮助。 在第二个示例中,艺术家可以拥有一把吉他。因为有箭头而另一侧没有箭头,所以我们知道吉他不认识艺术家。吉他是一种可以完全独立存在且不需要任何人的物体。 在第三个示例中,您看到了婚姻。真的很简单;丈夫认识妻子,妻子认识丈夫。在我们的情况下,丈夫只有一个妻子,反之亦然。

我们如何通常在代码中实现这一点?

class Husband
    Wife bestWomanInTheWorld;

    public Husband(Wife theWife)
        this.bestWomanInTheWorld = theWife;
    

因为丈夫总是需要妻子,所以我们将required关系放在构造函数中。因为艺术家可以拥有一把吉他,我们将把构造函数留空,如下所示:

class Artist
    List<Guitar> guitars;

    public Artist()
    

    public AddGuitarToCollection(Guitar newGuitar)
        Guitars.Add(newGuitar);
    

所以,这就是我们在代码中实现这一点的方式(大多数时候!)。如果您是编程新手,通常不需要不同类型的线条和箭头。保持简单。

箭头 2:依赖

好的,所以我们知道了我们将在大多数时间使用的正常关联。但是我们什么时候会使用“依赖”箭头呢?好吧,让我们定义一个依赖项(***):

Dependency is a weaker form of bond which indicates that one class depends on 
another because it uses it at some point in time. One class depends on 
another if the independent class is a parameter variable or local variable of 
a method of the dependent class. This is different from an association, where 
an attribute of the dependent class is an instance of the independent class. 
Sometimes the relationship between two classes is very weak. They are not 
implemented with member variables at all. Rather they might be implemented as 
member function arguments.

如果存在需要存在的连接、关系、关联等,则到 classA 才能工作;这是一个依赖。示例:丈夫需要妻子存在。汽车需要***才能成为汽车(和驾驶)。汽车工厂需要一个汽车类来制造一个对象。您的 RSSNewsItem 类需要一个 XMLReader 类来做任何事情。

什么时候使用?

嗯,这是我眼中唯一有效的问题;因为谷歌对你的问题显示了很多有效的答案。尽量不要在类图中使用依赖项,因为这通常意味着您不够具体。始终以关联、实现等为目标。仅在需要使用其他类而不维护关系时才使用实现(在我看来)。例子;实用程序类(如 XMLReader)。

如果您在阅读完此完整说明后有任何疑问,请随时提出。 :-)

【讨论】:

注意不要将可导航性(箭头)与所有权混淆。所有权被建模为关联末尾的子弹(未在您的示例中显示)。 是的,这是真的,但事实是;几乎没有人使用所有权项目符号,它超出了答案的范围,并且在大多数情况下没有必要(仅在不清楚的情况下)。这也是我不鼓励任何人使用依赖关联的原因。【参考方案5】:

虚线表示依赖于(箭头方向)。假设您已将源代码整齐地组装到每个类的单独文件和标题中 - 赠品只是代码包含 #include ClassB.h 行。

然而事实上,所有的类关系(泛化、实现、组合、聚合、关联等)都继承了依赖关系。出于这个原因,我在编写代码时从不使用虚线箭头。在可能的情况下,我的目标是用更具体的术语记录这种关系,例如。菱形、三角形等。如果我不知道确切的关系,我的起点是带箭头的实线(关联,具有(隐式)依赖)。

尽管如此,虚线箭头符号在 UML 建模的其他方面也很有用,例如。例如,在用例分析中显示对需求的依赖关系。 注意 思想警察会让我们尽可能通过使用接口(纯虚拟类)来减少类之间的耦合和依赖关系。

虽然纯虚拟类提供了多重继承的前景,并且尽可能地在类之间实现了最紧密的耦合。接口类的优点是它们完全由暗物质制成,因此对警察来说完全不可见。考虑到这一点,可以编写类之间显然为零耦合的 c++ 代码——他们喜欢这种做法,因为他们从来没有真正理解所有那些看起来很有趣的符号。

【讨论】:

【参考方案6】:

虚线表示实现(一个接口) solid 表示扩展(基类)

【讨论】:

这是完全错误的。泛化(扩展)和实现(实现)有一个封闭的箭头。

以上是关于UML 关系 - 虚线与实线的主要内容,如果未能解决你的问题,请参考以下文章

UML速查

UML类图

UML中的关系及表示

UML类图

UML类图详解

UML类图详解