非虚拟接口(NVI)习惯用法在C#和C ++中一样有用吗?

时间:2010-02-26 09:13:20

标签: c# c++ design-patterns idioms non-virtual-interface

在C ++中,我经常需要NVI来获得API的一致性。不过,在C#中我没有看到它用得那么多。我想知道这是因为C#作为一种语言,提供的功能使得NVI不再需要吗? (尽管如此,我仍然在C#中使用NVI。)

4 个答案:

答案 0 :(得分:8)

C#通过取消多重继承来解决NVI问题。虽然我认为多重继承会产生更多的邪恶而不是好的,但对于NVI来说(大多数情况下)是必要的。跳到脑海的最简单的事情是:C#中的一个类不能实现多个NVI。一旦发现C#/ NVI串联的这种令人不快的方面,放弃NVI比C#容易得多。

顺便说一下,谈论方面。这是一个非常有趣的概念,它的目标与NVI的目标完全相同,只是它试图查看问题的“真正的本质”,并“恰当地”解决它,可以这么说。 Take a look

就.NET Framework而言,有一种机制可以做到这一点:注入“正交”的代码,也就是说,注入手头的主要逻辑。我在谈论MarshalByRef / TransparentProxy的所有业务,我相信你已经听说过了。但它确实会严重影响性能,所以这里没有什么好运。

还有许多尝试通过其他技术实现相同的概念,从建筑外墙到上面提到的脏业务到MSIL的后期处理。

后一种方法恰好吸引了你的最多,因为它可以变得透明(通过将所需的步骤合并到一个构建例程中),它不会影响性能(实际执行“正交”不仅仅是绝对必要的“代码”并且它不涉及某种“黑客攻击”或逆向工程,因为MSIL是开放的并且有很好的文档记录。

Here可以更详细地找到这些要点,以及更多信息和实际工具的链接。使用Google也可以达到同样的目的。 : - )

祝你好运。

答案 1 :(得分:5)

我认为解释只是在C#中,“传统的”Java风格的OOP更加根深蒂固,NVI与此背道而驰。 C#具有真正的interface类型,而NVI依赖于实际上是基类的“接口”。无论如何,这就是用C ++完成的,所以它很适合。

在C#中,它仍然可以完成,它仍然是一个非常有用的习惯用语(更重要的是,我会说,比“普通”接口),但它要求你忽略内置的语言功能。

许多C#程序员不会认为NVI类是“适当的接口”。我认为这种精神抵抗是导致它在C#中不太常见的唯一原因。

答案 2 :(得分:4)

Trey Nash在他的书Accelerated C#中将NVI模式作为C#中的规范形式进行了宣传。

我不知道是谁写了你引用的文章(More C++ Idioms/Non-Virtual Interface),但我觉得作者错过了这一点。

...

接口与抽象类

我认为,哲学上,完全抽象的类(即没有任何实现)与接口之间没有什么区别(在C#中)。从表面上看,它们都可以提供可以执行的方法的签名,并且需要其他东西来实现该功能。

使用C#,如果您需要的是接口,您将始终编程到接口。您只使用(抽象)基类,因为您也希望实现重用。

除了提供类层次结构作为接口的默认实现之外,许多代码库还将这些和程序组合到接口。

C

中接口的NVI

如果你在C ++中使用NVI的唯一动机是拥有一个接口,那么不,你不会在C#中使用它,因为语言/ CLR提供接口作为一流的功能。

NVI和对象层次结构

在我看来,NVI从来就不是关于接口的。它始终是实现template method模式的绝佳方式。

有用性体现在代码生命周期维护(易于更改,扩展等),并提供了更简单的继承模型。

我的观点:是的,NVI在C#中非常有用。

答案 3 :(得分:0)

我认为NVI在C#中和在C ++中一样有用。我看到它在我公司经常使用。