我经常对 UML 感到困惑,这种情况也不例外。假设我有一个接口 IAnimal,类 Food 和 Cat:

interface IAnimal {
    void Feed(Food food);
}

class Cat : IAnimal {
    void Feed(Food food) {
        //code
    }
}

关于为这 3 个元素绘制 UML 类图,我有 3 个问题:

  • 我认为我应该使用 IAnimal 和 Food 或 Cat 和 Food 之间的关联。关联线的一侧是否应该有箭头,如果有,那么在哪一侧以及为什么有?

  • 如果我在图表上将 Feed 编写为 IAnimal 方法,我应该在 Cat 类中编写 Feed 方法还是只编写其他 Cat 方法?

  • 最重要的是:关联应该是 IAnimal 和 Food、Cat 和 Food 之间,还是两者之间?

有帮助吗?

解决方案

UML定义了一些 关系 类型。

关系有多种不同的表示法:

  • 关联关系具有实体路径的基本符号
  • 依赖关系有一个虚线箭头的基本符号
  • 泛化关系的基本符号是带有三角形箭头的实线路径
  • 实现关系具有带有三角形箭头的虚线箭头的基本符号(依赖性和泛化的混合)

形象地

+---------------------------+
|       <<interface>>       |
|           IAnimal         |
+---------------------------+                        +--------+
| + Feed(food: Food) : void |- - - - <<use>> - - - ->|  Food  |
+---------------------------+                        +--------+
              ^
             /_\
              |

              |

              |
        +-----------+
        |    Cat    |
        +-----------+

那是:

  • 之间的关系 IAnimalFood 是一个 用法 关系。这显示为与构造型“use”的依赖关系
  • 之间的关系 IAnimalCat 是一个 实现 关系。

关联关系用于表示 连接 两个或多个分类器之间。这意味着至少有一个类具有 属性 另一种类型(或集合)。事实上,属性和关联端包含相同的信息并且可以互换。

因此,恕我直言,您描述的关系不应建模为关联。

其他提示

假设有一个类图,您应该在 IAnimal 和 Food 之间有一个“use”关联,在 Cat 和 IAnimal 以及 Dog 和 IAnimal 之间有一个“is a”关联:

    IAnimal ----> Food
     ^   ^
    //   \\
   //     \\
 Cat      Dog

您对这类东西的挑剔程度在很大程度上取决于您最初使用 UML 的目的。

如果您有某种奇特的 UML 到代码转换器,那么您需要挑剔(但看起来您对代码比对框和线更舒服 - 那么您为什么要使用这样的工具?)

如果您只是使用 UML 与其他人进行交流,那么您可以不那么挑剔。

Craig Larman 的“应用 UML 和模式”强调了这一点,其中包含看起来像是在白板上绘制的图表。UML 标准规定应该加点的实线在这种图中就可以了。所以还有箭头等等。

我很清楚这条线应该从 IAnimalFood.

箭头是否增加清晰度(对于人类读者而言)是一个选择问题,但它表示单向关系:

这篇介绍性文章:

"在单向关联中,两个 类是相关的,但只有一个 类知道 存在"。

我认为 IAnimal 会有 HAVE-A 食物,因为它会被代谢,但如果你真的想表示 HAS-A,我认为它应该是一个聚合(空心菱形)或组合符号(填充菱形),具体取决于级联删除特性。

Martin Fowler 认为 UML 有两种思想流派。还有“草图绘制者”,他们使用白板和奇怪的纸上的符号向其他开发人员传达足够的想法。

还有一些人将 UML 视为工程图,必须捕捉设计的每一个细节。

我坚定地站在前一个阵营。作为一名前工程师,我可以根据个人经验告诉您,UML 不具备真实工程图的力量来完全捕获软件设计。

如果您碰巧相信后者,请使用 UML 进行完整的桌面或 Web UI 设计并将其发布在此处。

1) 接口 IAnimal 和 Food 类型之间不应编写任何关联。关联仅用于将类型与类内的属性连接起来。例如

class Animal
{
   Food foodEaten;
}

class Food
{
 //Implementation code
}

那么你应该编写一个关联来指示这两种类型之间的联系。

相反,您应该绘制一个依赖项,表明接口 IAnimal 依赖于 Food 类型。依赖关系的绘制方式与上图关联相同,只是将直线改为点线即可。

2)不,不要编写那些方法,也不要编写依赖项。仅将所有符号保留在 IAnimal 界面上

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top