Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 用于对象逻辑分组的空接口(抽象类),以避免LSP冲突_Design Patterns_Language Agnostic_Polymorphism - Fatal编程技术网

Design patterns 用于对象逻辑分组的空接口(抽象类),以避免LSP冲突

Design patterns 用于对象逻辑分组的空接口(抽象类),以避免LSP冲突,design-patterns,language-agnostic,polymorphism,Design Patterns,Language Agnostic,Polymorphism,在现实世界中,正方形是矩形,但对于程序而言,情况并非如此()。创建一个空白接口将对象逻辑地分组在一起是否被视为反模式/糟糕的编程?我的想法是,如果有一个空白的界面,就不可能在它的正下方违反LSP。下面是人为的例子 Abstract class Canine{ } Dog extends Canine {…} Wolf extends Canine {…} 不,它不会破坏LSP,因为基类无法完成任何操作,因此任何类都不可能违反LSP 我有时确实使用空接口将类分组在一起。我这样做是为了表

在现实世界中,正方形是矩形,但对于程序而言,情况并非如此()。创建一个空白接口将对象逻辑地分组在一起是否被视为反模式/糟糕的编程?我的想法是,如果有一个空白的界面,就不可能在它的正下方违反
LSP
。下面是人为的例子

Abstract class Canine{ }  

Dog extends Canine {…} 

Wolf extends Canine {…}

不,它不会破坏LSP,因为基类无法完成任何操作,因此任何类都不可能违反LSP

我有时确实使用空接口将类分组在一起。我这样做是为了表示某种意图。例如,我得到了一个名为
IMessage
的空接口,该接口用于显示类的目的只是在我的pub/sub框架中作为消息处理。(并且只允许在其中传输实现接口的类)


对我来说,它有助于确保班级遵循单一责任原则。(与不实现任何接口的消息类相比)

不,它不会破坏LSP,因为基类无法执行任何操作,因此任何类都不可能违反LSP

我有时确实使用空接口将类分组在一起。我这样做是为了表示某种意图。例如,我得到了一个名为
IMessage
的空接口,该接口用于显示类的目的只是在我的pub/sub框架中作为消息处理。(并且只允许在其中传输实现接口的类)


对我来说,它有助于确保班级遵循单一责任原则。(与未实现任何接口的消息类相比)

在您的场景中,这对我们有何帮助。我们有一个抽象类矩形?是什么阻止我们声称正方形延伸了矩形

在您的场景中,这对我们有何帮助。我们有一个抽象类矩形?是什么阻止我们声称正方形延伸了矩形

取决于它的用途

空接口不强加任何语法要求,因为没有可实现的方法

但是,接口可能会被记录下来,以强加语义要求,特别是如果
犬科
本身继承自
卡诺伊达
食肉动物
或任何东西。这使得空接口可能有用,因为它提供了自己的保证。所有食肉动物都有耳朵[*],但Canoidea的部分特征是耳朵的某些属性,这些属性不容易简单地表示为添加一个方法,因此实现接口成为一个承诺:“除了食肉动物,我的耳朵也会这样”

这意味着不再不可能违反LSP。您可能会意外地编写一个具有重写函数的子类,该函数返回12,这对于Carnivora是允许的,但Canine的语义表示它返回的值不会超过10

只添加语义的接口不一定很好使用,因为存在一些容易犯的错误。一个例子是C++中的代码> InputIterator < /COD>和前述迭代器< /代码>(当然,这些是模板概念,不是继承接口)。如果用错误的类标记类,编译器将永远不会注意到。但是如果你用
RandomAccessIterator
标记你的类,而实际上它只是一个
ForwardIterator
,那么当有人试图对它使用
operator+
时,编译器会注意到,因为
operator+
是RandomAccessIterator的一部分,而不是ForwardIterator

没有语义的空接口是没有意义的,因此可能是无用的。我能想到的它的唯一用途是作为一种变体——一些狡猾的代码可以测试对象是否是“Dog”或“Wolf”(或其他)的实例,并相应地做不同的事情。这可能不是一个很好的用途,因为它一开始可能不是很好的代码。如果可用,您还可以使用像
Object
这样的终极超类,因为无论哪种方式,代码都必须处理它无法识别和处理的类型。“狐狸到底是什么,我不能在这里使用狐狸”并不比“向量到底是什么,我不能在这里使用向量”好或坏,所以如果你理解的是狗和狼,那么接受狗与接受对象相比,没有什么真正的优势。它们都是变种,允许狗、狼以及其他任何人选择进入等级体系的东西

[*]是的,甚至是封条。他们只是没有耳廓。

取决于它的用途

空接口不强加任何语法要求,因为没有可实现的方法

但是,接口可能会被记录下来,以强加语义要求,特别是如果
犬科
本身继承自
卡诺伊达
食肉动物
或任何东西。这使得空接口可能有用,因为它提供了自己的保证。所有食肉动物都有耳朵[*],但Canoidea的部分特征是耳朵的某些属性,这些属性不容易简单地表示为添加一个方法,因此实现接口成为一个承诺:“除了食肉动物,我的耳朵也会这样”

这意味着不再不可能违反LSP。您可能会意外地编写一个具有重写函数的子类,该函数返回12,这对于Carnivora是允许的,但Canine的语义表示它返回的值不会超过10

只添加语义的接口不一定很好使用,因为存在一些容易犯的错误。一个例子是C++中的代码> InputIterator < /COD>和前述迭代器< /代码>(当然,这些是模板概念,不是继承接口)。