将 UML 组件映射到 C++ 的最佳方法是什么?

What is the best way to map an UML component to C++?

我有一个 UML 组件图,其中每个组件都 "connected" 到其他组件,或者通过为它们提供某些接口或通过要求其他组件提供的接口(它们使用 classic "lollipop" 表示法连接。

在较低的抽象层次上,我之前引用的每个组件都由 class 图.

描述

我知道如何将每个 class 图中包含的 UML classes 映射到 C++,因为该语言中有 class 的概念。

所以我的问题是:在这种情况下,将 UML 组件 的概念映射到 C++ 的 best/most 常用方法是什么?

也欢迎处理此特定主题的网络资源。

编辑:

我知道UML并没有给出最终的答案,我更想知道从业者通常是如何处理这个问题的。最先进的技术是什么?

UML 组件 不能(直接)映射到 C++ 或其他语言中,这与它们的 'implementation' 是 工件相反 例如,在那种情况下,通过一个库或一个简单的目标文件。

有关 组件 的要点,如规范 § 11.6.3.1 所述:

A Component is a substitutable unit that can be replaced at design time or run-time by a Component that offers equivalent functionality based on compatibility of its Interfaces

什么是组件?

组件是 self-contained 的可替换软件,可根据公开和使用的接口提供某些功能。

UML 组件(请参阅 Bruno's answer)对此类组件进行建模,但未阐明 design-time 或 run-time 替换的含义。 UML 的发明者在他们的书 统一软件开发过程 中阐明 UML 组件原则上应该属于实施模型,即:

describes how elements in the design model, such as design classes are implemented in terms of componenets such as source code files, executables an so on.

实践中的组件是什么?

Jacobson、Booch 和 Rumbaugh 在他们的书中添加了一些实用的组件示例(我在这里添加了一个简短的映射接口注释):

  • 一个executable:它的接口可能对应一个API和消息或数据格式
  • 一个库:它的接口是库的定义objects,它通过符号公开)
  • 一个或几个源代码文件:它的接口是编程语言的接口机制。例如,您可能拥有 C++ 源代码组件;
  • 一个数据库table:它的接口由DDL定义,查询语言的规范and/or DBMSAPI。

如何在C++中实现组件?

如何实现一个组件及其接口是完全开放的:一个 C++ 组件可以只是一个普通的执行程序table,它在更大的难题中扮演着明确定义的角色;或图书馆。

这使您的问题非常宽泛。但是,如果我们将答案缩小到 C++ 中的 source-code 个组件,我们可以走得更远。

在源代码的"higher level"处("higher"表示:"I use my file explorer and do not look into the files"):

  • 通常,一个接口是在一个或多个 C++ header 中定义的。在 headers 中,您可以声明函数或定义 classes,而无需提供实现。
  • 一个C++组件可以是一个,也可以是几个translation units的一组(即源代码文件)。这些可以位于它们自己的目录中,但它们不需要。
  • 组件通过包含相应的 C++ header 来使用所需的接口。它以一个或多个 header 的形式提供自己的接口,可以包含在其他地方。
  • 重要说明:我武断地将问题缩小到整个源文件,但实际上,没有什么能阻止您将多个组件分组到同一个源文件中。只是在实践中这会使组件的互换性降低:这就是为什么我没有提到它。
  • 不排除将来会有越来越多的C++组件看起来像C++ modules(C++20的特性)。

可以通过替换为 same interfaces defined in the headers 提供不同实现的实现文件来实现此类源组件的互换性。这种互换性只能在实施时发生。

在 "lower level" 的源代码中(即查看源文件),您还使用 C++ 语言功能来制作可以在 run-time 独立于 source-code 组织:

  • 语言特性和编程实践可以定义interfaces
  • 可以定义一个接口,例如 class 定义,或者更好的是 an abstract class,然后专门用于许多替代组件,这些组件都通过继承符合接口。
  • 引用、指针或(最好)smart-pointer 可用于使用接口,允许在运行时 select suitable 组件,例如使用工厂。

但这一切都一如既往地简化了:您还有另一种强大的 C++ 组件化形式:模板。模板是 compile-time 组件化并且独立于源代码结构:

  • 模板可以在 header 中定义提供的接口。不幸的是,除非您在 headers 中使用 headers(请参阅 boost 库作为一个非常强大的示例),否则很难将实现与实现分开。
  • 模板使用它们使用的所有类型的接口。不幸的是,它是所需接口的隐式定义。

结论/建议

即使缩小您的问题范围,也有很多方法可以在 C++ 中实现组件。老实说,我倾向于将组件主要用于高级 executable 组件和草图架构,而不是在 class 或文件级别对详细实现进行建模。如果我每次需要包含新的 header 时都必须更改我的模型,我很快就会忙于记录更改,以至于我不会再交付了,但我仍然重视 "working code" 超过 "comprehensive documentation" ;-)。