【问题标题】:Does composition apply to an implemented class when composing an interface?组合接口时,组合是否适用于已实现的类?
【发布时间】:2020-03-04 21:25:52
【问题描述】:

有一个类A、一个IB 接口和一个实现IB 接口的类B。类 A 有一个类型为 IB 的字段。在程序执行期间,该字段的值成为类B 的实例。这种情况如何绘制类图? AIB 之间是否存在“组合”关系,组合是AB 之间的关系,还是只是依赖关系?

【问题讨论】:

    标签: dependencies uml composition class-diagram


    【解决方案1】:

    这取决于您要赋予构造的语言和/或语义。

    使用基于引用的类的语言,如 java:

    • B 的实例始终可以共享,因此在 A 对象死亡后继续存在。这与 UML 中的组合相矛盾。
    • 聚合将允许共享 B。但不幸的是,聚合语义在 UML 中没有很好地定义,因此是模棱两可的。
    • 正常的关联是正确且明确的。

    在具有基于值的类(如 C++)的语言中:

    • 组合将适当地表示对象的联合生命周期
    • 但是,在您的情况下,IB 将是多态的。多态性需要一个指针。如果您使用unique_ptr<IB>,您将表达一个构图。其他指针可能允许共享对象,因此正常关联将是更好的表示。

    但是 UML 不是一种编程语言。它是一种建模语言。所以你应该在模型中表达你想要的语义。如果 IB 对象不希望被共享,并且不应该比 A 寿命长,那么组合适当地表明了这个意图。如果没有,请保持开放。

    【讨论】:

    • the instance of B could always be shared and therefore continue to live after the death of the A object。如果只有A 拥有指向它的链接,垃圾收集器不会删除对象B 吗?我不知道在 Java 中是如何工作的,但在 .Net 中它是这样工作的。基于此,构成在这里吗?类A和接口有什么联系?组合还是联想?还是依赖?
    • @AnthonyMinchenko 是的,如果只有一个 A 实例拥有 B 实例的句柄,那么垃圾收集器就会同时处理掉这两个实例。但问题是语言结构本身并不能保证没有其他 A 实例(甚至是 X 实例)引用同一个 B 实例。因此,用组合翻译语言结构会做出无法验证的假设。这就是为什么我坚持设计意图的原因:如果你不想共享一个 B 实例,那么你可以使用组合来表达这个意图。
    • 但是如果一个B类的对象只在A类内部创建,是它的字段并且没有其他类的对象可以访问它,那么这是一个明显的组合吗?
    • @AnthonyMinchenko 让我们反过来说:如果我有一个带有comopsition 的UML 图,我肯定会按照你的描述开始实施它。从语言结构推断设计并不简单:如果仅在 A 内部创建 B,并且如果 A 有 copy constructor,我可能最终会得到多个 A 共享同一个 B。
    • 仔细分析了我的代码后,我注意到我正在使用Mediator 模式(也称为:IntermediaryController)来减少许多类之间的连接性,因为将这些链接移动到一个中介类中。因此,AB 类之间没有严格的联系。这是组合 BMediator 和 a 对中介的依赖。
    猜你喜欢
    • 2015-09-16
    • 2014-06-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-19
    • 2011-11-27
    • 1970-01-01
    • 2018-02-17
    相关资源
    最近更新 更多