简体   繁体   English

UML概括与实现

[英]UML generalization and realization

I am pretty new to UML, so I have some questions about Generalization and Realization. 我对UML还是很陌生,所以我对通用性和实现有一些疑问。 I am modeling the behavior of an electronic microcontroller and I need to generate C++ code from the UML description. 我正在对电子微控制器的行为进行建模,需要从UML描述生成C ++代码。

As far as I know, a class realizes an interface, that means it may provide the implementation of an interface. 据我所知,一个 实现一个接口,这意味着它可以提供接口的实现。 A generalization relationship may exist between two classes. 两个类之间可能存在概括关系。 In that case the derived class inherits all the members of the base class and gains access to public and protected members. 在这种情况下,派生类将继承基类的所有成员,并获得对公共成员和受保护成员的访问权限。

Here is my question (I am using Visual Paradigm as modeling tool). 这是我的问题(我正在使用Visual Paradigm作为建模工具)。 Let us assume we have a module of a microcontroller, namely the Timer . 假设我们有一个微控制器模块,即Timer We have a set of operations we can perform, say initTimer() , startTimer() , stopTimer() and so on. 我们有一组可以执行的操作,例如initTimer()startTimer()stopTimer()等。 Actually these functions define a kind of API. 实际上,这些函数定义了一种API。 We may have different classes of Timer , say TimerA , TimerB , TimerC that inherit (or implement?) all of the cited operations. 我们可能有不同的Timer类,例如TimerATimerBTimerC ,它们继承(或实现?)所有引用的操作。 The picture will make the scenario clearer, probably. 图片可能会使情况更清晰。 [C] means classifier. [C]表示分类器。

                        +----------------------------------+   
                        |              <<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 allows the user to put code iniside each function. Visual Paradigm允许用户将代码放在每个函数的内部。 I ask you which kind of relationship the arrows should be. 我问你箭头应该是什么样的关系。

1) Generalization : Timer class with a set of operations. 1) 泛化 :带有一组操作的Timer类。 Each operation has its code implementation. 每个操作都有其代码实现。 Two derived classes TimerA and TimerB with generalization link inheriting the operations of class Timer . 具有泛型链接的两个派生类TimerATimerB继承了Timer类的操作。

2) Realization : Timer is an interface (not a class as shown) and two realizing classes TimerA and TimerB . 2) 实现Timer是一个接口 (不是如图所示的类),并且是两个实现类TimerATimerB The critical point is the following. 关键点如下。 Although Timer is an interface and its operations should not contain implementaion details, VP allows to write implementation code for the three operations. 尽管Timer是一个接口,并且其操作不应包含实现细节,但是VP允许为这三个操作编写实现代码。 During code generation, an interface C++ class Timer is created: initTimer() , startTimer() and stopTimer() are virtual members of Timer with no code (as it should be). 在代码生成过程中,将创建接口C ++类TimerinitTimer()startTimer()stopTimer()Timer 虚拟成员没有任何代码 (应该如此)。 A C++ class TimerA is generated and this inherits class Timer members; 生成一个C ++类TimerA ,它继承了类Timer成员。 in addition the three operations of Timer are copied among the memebers of TimerA with the code implementation that I wrote for the operations of the interface class. 此外,使用我为接口类的操作编写的代码实现,在TimerA之间复制了Timer的三个操作。 This happens for TimerB as well. TimerB也会发生这种情况。

In your opinion which of the two descriptions is better? 您认为这两种描述中哪一种更好? Is it correct to write code implementation for the operations of an interface even if I know that, after code generation, will be transferred towards the realizing classes? 即使我知道在代码生成之后,将代码转移给实现类,为接口的操作编写代码实现是否正确?

In your opinion which of the two descriptions is better? 您认为这两种描述中哪一种更好?

In my opinion option 3 sketched in the picture below is better. 我认为下图中的选项3更好。 Timer would be reusable (conceptually final ) universal class, it's instance only configured by the singleton wrappers and linked by usage dependency relationship Timer将是可重用的(概念上是final )通用类,它的实例仅由单例包装器配置并通过使用依赖关系进行链接

在此处输入图片说明

VP allows to write implementation code for the three operations. VP允许为这三个操作编写实现代码。 During code generation...Is it correct to write code implementation for the operations of an interface...? 在代码生成期间...为接口的操作编写代码实现是否正确...?

I don't know how to correctly configure Visual Paradigm's code generator to produce what you want, but although C++ interface is 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. 我不知道如何正确配置Visual Paradigm的代码生成器以生成所需的内容,但是尽管C++接口只是一个类,并且此概念没有特殊的keyword ,但UML接口仅是contract描述。没有耦合的实现。 Some languages like C# or Java have special interface keyword for this purpose, with no-code rule hardcoded in the compiler. 一些语言(例如C#Java)为此具有特殊的interface keyword ,在编译器中硬编码了无代码规则。

Thus, although Visual Paradigm can perhaps generate the code which you want at the end, from UML perspective, modeling an interface with code is wrong 因此,尽管Visual Paradigm也许可以最终生成所需的代码,但从UML角度来看,使用代码对interface进行建模是错误的


Make your choice. 做出你的选择。 If you want just code that does The something, then go and hack it anyway which works (as @gilead-silvanas suggests). 如果您只想要执行The what的代码,则无论如何都要去破解它(如@ gilead-silvanas所建议)。 If you want to practice UML for use in your future projects using different languages, then don't. 如果您想练习UML以在将来的项目中使用不同的语言来使用,那就不要了。

Also there's a time when the initial generated code will depart from the initial design drawings and from the code generator and you'll edit it by hand, even if you'd use a tool like Quantum Leaps Modeler for embedded systems . 还有一段时间,即使您为嵌入式系统使用了诸如Quantum Leaps Modeler之类的工具,初始生成的代码也会与初始设计图和代码生成器背道而驰,您需要手工进行编辑。

I'd reconsider (regularly) if fighting with the design tool over-weights the code generation benefits 我会(定期)重新考虑是否与设计工具抗衡了代码生成的好处

Probably this is just a shorthand for VP to make things quicker. 可能这只是副总裁加快工作速度的捷径。 As you said, upon code generation, it clears those codes anyway from the interface and put it in the realizing classes. 如您所说,在代码生成时,无论如何它都会从接口清除这些代码,并将其放入实现类中。 I don't see anything wrong with that because what matters is the generated code, which in your case is correct. 我认为这没有任何问题,因为重要的是生成的代码,在您的情况下这是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM