UML泛化与实现

UML generalization and realization

我对 UML 很陌生,所以我对泛化和实现有一些疑问。我正在对电子微控制器的行为进行建模,我需要根据 UML 描述生成 C++ 代码。

据我所知,一个class实现一个接口,也就是说它可能提供一个接口的实现界面。 两个 class 之间可能存在 泛化 关系。在这种情况下,派生 class 继承 基 class 的所有成员并获得对 public 和受保护成员的访问权。

这是我的问题(我使用 Visual Paradigm 作为建模工具)。 让我们假设我们有一个微控制器模块,即Timer。我们有一组可以执行的操作,比如 initTimer()startTimer()stopTimer() 等等。实际上这些函数定义了一种API。我们可能有 Timer 的不同 class,比如 TimerATimerBTimerC 继承(或实现?)所有引用的操作。图片可能会使场景更清晰。 [C] 表示 classifier.

                        +----------------------------------+   
                        |              <<SW>>              |
                        |           <<Singleton>>          |
         +--------------|              TimerA              |
         |              +----------------------------------+
         |              | -instance : TimerA* = null [C]   |
         |              | -instanceFlag : bool = false [C] |
         |              | -moduleAddress const = 0x0010    |
         |              +----------------------------------+
         |              | -TimerA()                        |
         V              | +getInstance() : TimerA* [C]     |
+---------------+       +----------------------------------+
|    <<SW>>     |       
|     Timer     |
+---------------+
| +initTimer()  |     
| +startTimer() |<-----------------------+
| +stopTimer()  |                        |
+---------------+      +----------------------------------+ 
                       |              <<SW>>              |
                       |           <<Singleton>>          |
                       |              TimerB              |
                       +----------------------------------+
                       | -instance : TimerB* = null [C]   |
                       | -instanceFlag : bool = false [C] |
                       | -moduleAddress const = 0x0020    |
                       +----------------------------------+
                       | -TimerB()                        |
                       | +getInstance() : TimerB* [C]     |
                       +----------------------------------+

Visual Paradigm 允许用户将代码放在每个函数中。我问你箭头应该是哪种关系

1) 泛化: Timer class 一组操作。每个操作都有其代码实现。两个派生的 classes TimerATimerB 泛化 link 继承 class Timer.

的操作

2) 实现Timer是一个接口(不是如图所示的class)和两个实现 classes TimerATimerB。关键点如下。虽然 Timer 是一个接口,它的操作不应该包含实现细节,但 VP 允许为这三个操作编写实现代码。在代码生成期间,将创建接口 C++ class TimerinitTimer()startTimer()stopTimer() 虚拟成员 Timer无代码(应该是)。生成 C++ class TimerA 并继承 class Timer 成员;此外,Timer 的三个操作在 TimerA 的成员之间复制,并使用我为接口 class 的操作编写的代码实现。 TimerB 也会发生这种情况。

您认为这两种描述哪种更好?为接口的操作编写代码实现是否正确,即使我知道,在代码生成后,将转移到实现 classes?

可能这只是一个 shorthand VP 让事情变得更快的方法。正如您所说,在代码生成时,它无论如何都会从接口中清除这些代码并将其放入实现 类 中。我认为这没有任何问题,因为重要的是生成的代码,在您的情况下是正确的。

In your opinion which of the two descriptions is better?

在我看来,下图中勾勒的选项 3 更好。 Timer 将可重复使用(概念上 final)通用 class,它只是实例 配置 由单例包装器并由 usage dependency relationship[ 链接=26=]

VP allows to write implementation code for the three operations. During code generation...Is it correct to write code implementation for the operations of an interface...?

我不知道如何正确配置 Visual Paradigm 的代码生成器来生成你想要的,但是虽然 C++ 接口是 just a class like any other and there's no special keyword for this concept, UML interface is meant to be only description of a contract with no coupled implementation. Some languages like C# or Java 有特殊的 interface keyword为此,在编译器中硬编码了无代码规则。

因此,虽然 Visual Paradigm 最后可能会生成您想要的代码,但从 UML 的角度来看,用代码建模 interface 是错误的


做出你的选择。如果您只想要执行 The 某事的代码,那么无论如何都要破解它(正如@gilead-silvanas 所建议的)。如果您想练习 UML 以便在未来的项目中使用不同的语言,那就不要。

还有一段时间,初始生成的代码会偏离初始设计图和代码生成器,您将手动编辑它,即使您会使用像 Quantum Leaps Modeler for embedded systems 这样的工具。

我会(定期)重新考虑与设计工具的斗争是否会过度重视代码生成的好处