实现对另一个接口的依赖

Dependency of the implementation on another interface

考虑从 YT 教程视频中提取的 UML 图(观察者模式):

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

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

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

澄清一下——我不是在谈论这个具体的 UML 图——这种方法(“缺少”依赖项)似乎是 most/all 类似 [=41] 的 UML 图的规范=]关系。这是为什么?

为什么?

首先,该图并不完全符合叙述:该图显示了 ConcreteObservable,它是 IObservable 的特化(即它继承而不仅仅是实现)。 ConcreteObserverIObserver 相同。

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

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

习惯了!

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