面向实现的类图关系重定义

在软件开发过程中,理解和表达类之间的关系是至关重要的。UML(统一建模语言)是业界广泛使用的建模语言之一,其类图是描述类之间关系的常用工具。然而,UML类图中的标准符号可能不足以清晰地表达所有类型的类实例关系,尤其是在复杂的项目中。本文旨在探讨如何重新定义这些符号,以便更精确地表达类之间的关系,特别是实现和创建关系。

UML中,类之间的关系通常通过实现(Implementation)、派生(Derivation)、依赖(Dependency)、关联(Association)、聚合(Aggregation)和组合(Composition)等概念来表达。这些关系有助于理解类如何相互作用。然而,这些关系往往只关注引用本身,而忽略了类之间的其他重要属性。

问题

标准的类实例关系虽然适用于建模引用关系,但它们并不能涵盖类实例关系的所有属性。例如,在工厂方法模式中,创建者(Creator)使用工厂方法(FactoryMethod)来创建产品(Product)。如果没有图注、解释或特定的命名约定,很难从类图中看出ConcreteCreator和ConcreteProduct之间的依赖关系是一种创建关系。此外,当项目规模较大,特别是涉及到依赖注入框架时,这种关系可能会变得非常复杂。

分析

需要一种方法来建模引用和创建关系,理想情况下只使用现有的符号。下表展示了希望建模的组合关系:

创建 引用 生命周期控制

注:NYN和NNY被省略,因为没有引用就不能有生命周期控制。

表格显示创建是一个独立的二元关系——要么创建,要么不创建。引用和生命周期控制是一个耦合的三元关系——没有引用+没有LCC,有引用+没有LCC,有引用+有LCC。它们一起构成了六种不同的关系。

解决方案

幸运的是,这就意味着创建关系可以通过线条来定义,而引用关系可以通过菱形来定义。尽可能保持符号的传统含义,提出的类关系建模系统如下:

在之前提到的工厂方法示例中,不再需要指定创建的脚注——只需使用实线即可。下面是一个更复杂的抽象工厂模式示例:

// 假设的代码示例 class AbstractFactory { public Product createProduct(); } class ConcreteFactory implements AbstractFactory { public Product createProduct() { return new ConcreteProduct(); } } class Client { private Factory factory; private Product product; public Client(Factory factory) { this.factory = factory; } public void operation() { this.product = factory.createProduct(); } }

在标准图中,没有脚注,表达力大大降低。只指定了引用耦合。在提议的图中,立即表达了多个实现细节。工厂和产品之间的关系纯粹是创建关系。客户端控制工厂实例的生命周期,并持有产品的引用,但不创建它们。这使得模式一目了然。工厂创建产品;客户端使用它们。

最终思考

在这个新系统中,类关系不再受到依赖或聚合等泛化概念的约束。所有关系都定义得很好。此外,由于创建和引用关系是独立的,符号变得分层,整体关系是由这些符号构建的。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485