【问题标题】:Dependency of the implementation on another interface实现对另一个接口的依赖
【发布时间】:2021-10-28 00:49:55
【问题描述】:

考虑这个来自 YT 教程视频的 UML 图(观察者模式):

IObservable 依赖于IObserver,因为它的方法采用该类型的参数。 Concrete* 类当然实现了它们各自的接口。 ConcreteObserver 依赖于 ConcreteObservable(而不是 IObservable,请注意),因为它在其构造函数中将其作为参数。

我觉得不对的是ConcreteObservable 需要实现IObservable 的方法,所以它也直接“使用”IObserver。图表上的那些之间不应该有依赖关系吗?

我知道它只是实现 IObservable 的方法,ConcreteObservableIObserver 之间的关系有点间接地由图中的其他箭头显示,但就像我提到的那样,我感觉不对因为它们之间存在 直接依赖关系,并且未在图表中显示。

为了澄清——我不是特别在谈论这个具体的 UML 图——这种方法(带有“缺失”依赖项)似乎是大多数/所有类似类关系的 UML 图中的规范。这是为什么呢?

【问题讨论】:

    标签: inheritance interface dependencies uml class-diagram


    【解决方案1】:

    为什么?

    首先,该图与叙述不完全对应:该图显示了一个ConcreteObservable,它是IObservable 的特化(即它继承而不仅仅是实现)。 ConcreteObserverIObserver 也是如此。

    UML 语义非常明确:如果ConcreteObserver 继承 来自IConcreteObserver,它不仅继承了它的公共操作和属性,还继承了它的关系。因此,红色箭头将是多余的,因为它已经是隐含的。此外,这种冗余会引入歧义:专业读者会想知道它是否与现有关联之上的关联相同或其他关联。在这种情况下,您需要更多元素来消除歧义(例如红色关联和原始关联之间的继承箭头)。

    对于接口实现(到超类的线应该用虚线表示)类似:实现接口的类必须实现接口指定的内容,包括它的关联。所以它不是继承的,但同样,关联是隐式的。

    习惯吧!

    但是,与其在图表中添加不必要的元素,使用高级 UML 功能来消除歧义,从而使图表更难阅读,我建议您习惯这种表示形式:您会在您的职业生涯,重要的是要识别“模式”(这里不一定是观察者模式,而是使用接口或泛化/专业化解耦抽象的更多技术)。

    【讨论】:

    • 所以这种行为(暗示依赖)只出现在继承和接口实现中?在所有其他情况下,我应该显式地绘制所有依赖项?
    • @NPS 是的,没有继承和实现,虽然允许建模者不显示所有内容,但没有隐式关系(例如,如果 A 与 B 相关联,而 B 与 C 相关联,您可以间接推断出 A与 C 相关联。您可以将其显示为派生关联,或者您可以决定不显示此类间接关联。选择权在您手中)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    相关资源
    最近更新 更多