假设我有一个接口Interface
和一个实现ConcreteClass
的具体类Interface
。现在考虑第三类MyClass
。如果MyClass
的实例包含对ConcreteClass
的引用:
Interface ref = new ConcreteClass();
那么我应该在UML类图中将MyClass
与Interface
或ConcreteClass
相关联吗?
谢谢
答案 0 :(得分:0)
这取决于MyClass
的公共接口定义的内容。
如果公共接口使Interface
可用,那么您应该链接到图表上的那个。这是通常的方法,因为Interface
是一般类型并指定合同。除非您有理由限制为ConcreteClass
,否则请不要。
如果公共界面使ConcreteClass
可用,那么您应该链接到图表上的那个。
事实上,在运行时,Interface
类型的变量实际上包含ConcreteClass
的实例是不重要的。该图表示关系。
答案 1 :(得分:0)
有两种方式可以呈现ref
的{{1}}变量:您可以将其显示为属性或关联。然后,MyClass
接口有两种替代符号:Square与接口构造型或圆形。这使得2 * 2 = 4个选择。
Interface
显示为关联并使用方形界面表示法。
此处您无法显示ref
所需的初始值。那是因为您无法在关联中显示默认值。
ref
显示为关联,但为界面使用圆符号。
与之前的替代方案一样,此处再次显示初始值。
ref
显示为属性并使用方形界面表示法。
您可以在此处显示默认值,因为您可以为属性执行此操作。 ref
和MyClass
之间的关系表示为依赖关系。 Interface
和MyClass
之间的依赖关系也是如此。
请注意,此依赖关系(ConcreteClass
依赖于MyClass
)也可以在备选方案1和2中显示,您可以添加从ConcreteClass
指向MyClass
的依赖关系箭头(虚线) }。
ConcreteClass
显示为属性并使用圆形界面表示法。
此处您可以显示默认值。
如果我们也计算从呈现或不呈现依赖性的替代方案,那么至少有6种方式来呈现相同的东西。现在的问题是选择哪个。
这取决于您希望使用图表可视化的内容以及图表的目标对象。在这种情况下,如果ref
的初始化是消息,那么您应该使用提供它的替代方法。如果它不那么重要,那么您可能更喜欢将ref
显示为关联的图表。
在一个真正的问题中,你有更多的元素,所以它提供了更多的选择。你总是要决定要呈现什么以及如何呈现。
编辑:一些参考文献可以帮助您理解界面实现的表示法。
根据wikipedia:
实现是类,接口之间的关系, 将客户端元素与a连接的组件和包 供应商元素。类和类之间的实现关系 接口以及组件和接口之间显示该类 实现界面提供的操作。
您可以在uml-diagrams.org找到一些快速参考示例和大量信息。
这个优秀的答案Explanation of the UML arrows将为您提供更多示例。
Here您还可以找到有关实现的更多信息。
答案 2 :(得分:0)
仅使用界面。关键是你想要接口的行为。无论该接口的实现是什么,都是不重要的。 MyClass与接口有关系,而不是接口的实现。
这个原则叫做Design By Interface。在nakosspy给出的答案中,这是他的第一张照片。但是,将ConcreteClass的实现排除在外是更好的。在该概念层面,实施并不重要。如果有一个指向接口的变量,那么对于受过良好教育的读者来说,显然也应该有一个具体的实现。
如果您要引用ConcreteClass,那么每次更改接口的实现时都必须更改图表。那不是你想要的。这是糟糕的编码实践和糟糕的实践。
将MyClass和Interface之间的关系声明与接口的实际实现分开是一种很好的编码实践。例如:
Interface ref = new ConcreteClass();
永远不应该发生在MyClass类中。
你应该有这样的东西:
class MyClass
Interface ref;
setRef(){
ref = InterfaceImplementation();
}
}
这样可以在不改变MyClass中的一行代码的情况下更改Interface的实现。当你编写一个类时,这可能看起来很麻烦,当你管理数百个类时,请考虑它。
答案 3 :(得分:0)
所以:这取决于。
将MyClass
与ConcreteClass
或Interface
相关联同样合法。您将无法在UML规范中找到问题的答案。为什么?因为答案在于您的问题域,而不是建模语言。
考虑两个人为的例子来说明这一点。
示例1:类之间的关联
替换:
ICanBark
Interface
{li> Dog
ConcreteClass
{li> Trainer
MyClass
我们假设我们想要捕获的关联是Trains
,即
在这种情况下,由于“小狗”而不是“Barkiness”存在关联。所以它恰好存在于两个类之间。
示例2:类和接口之间的关联
替换:
ILogger
Interface
{li> FileLogger
ConcreteClass
{li> Application
MyClass
在这种情况下,关系是关于'Logginess',而不是'Fileness'。 Application
不应该关心接口是如何实现的;它只是想要一种记录消息的方法。因此,关联存在于类和接口之间
<强>摘要强> 与协会的情况几乎一样,解决问题的关键在于问题域本身 - 而不是建模语言。
第h
答案 4 :(得分:0)
您可以将具体类的引用定义为:
没有更多选项可供选择