为什么.NET应用程序中使用的接口如此丰富?

时间:2011-02-16 09:44:07

标签: .net architecture coding-style

最近,我开始研究一个大型的主流项目,为一个我无法透露的客户提供面向公众的电子商务平台。

我与经验丰富的开发人员合作,他们在伦敦金融城的许多项目中拥有多年的经验。

似乎每个人都在很大程度上进入界面。它是压倒性的,我现在怀疑我以前做过的所有事情,即使用抽象基类。

.NET不是COM,它不是基于接口的编程平台。我是否遗漏了某些东西,或者这只是一种群体心态 - 多年的编程已经成为.NET领域公认的规范?

由于

7 个答案:

答案 0 :(得分:20)

接口促进松散耦合,并且易于模拟。它们使API与实现之间的分离非常明确。

当然,当不同实现之间存在共同功能时,您可以使用抽象基类(如果需要,仍然可以在抽象类之上设置接口)但是如果所有在抽象类中是抽象的,并且没有字段,为什么通过抽象类使用你的一次继承?哪个好处?

答案 1 :(得分:4)

抽象类和接口有两种不同的用途 第一个用于提供父/子继承 第二个用于指定实现类的特定行为 我同意接口因为错误的原因而经常使用恕我直言。

编辑:
此外,广泛使用界面可能会导致装箱/拆箱问题:
当将实现接口的值类型传递给具有interface-type作为其参数的方法时,可能会发生这种情况。我个人不得不面对这个问题并重构代码以摆脱接口(虽然它很方便API关注)以获得性能,因为有问题的类在运行时被使用并传递了数百万次

答案 2 :(得分:2)

这完全取决于你想要达到的目标。接口和抽象类之间的主要区别在于类可以继承多个接口但只能继承一个抽象类。所以两者都有自己的目的。

答案 3 :(得分:2)

摘要和界面有不同的用途。

派生的“是”某事。实现接口“可以做”某事的类。

类派生自基类,因为它们希望专门继承父实现的功能和行为。这可以进一步链接,因为系列中的一个组可能需要保留一组共同的可重用行为,而另一组则需要分支以实现一组不同的常见行为。

e.g。 System.Web.UI.Control系列类 - 所有类都具有ASP.NET服务器控件的通用功能,但是在该系列的下游实现差别很大。但是他们仍然会在一天结束时将HTML呈现给网页。

另一方面,接口只是定义了您希望实现类执行的操作,而不是完全相似。关于如何实现这些功能,没有硬性定义。实际上,可以很好地完成实现以实现主系统的完全不同的东西,但是以模板化的方式(接口)构造,以允许系统以标准方式管理它们。

e.g。 IHttpModule,Providers,System.Runtime.Remoting.Channels等。

答案 4 :(得分:1)

接口指定类型的功能,而不是继承关系。接口的“好”示例是封装了可能适用于各种非常不同的具体类型的非常一般的概念,这些概念可能没有任何共同之处(考虑IComparableIEnumerable)。

使用类层次结构或基于接口的方法来决定什么是“正确的方法”并不总是容易的。我认为接口是提高抽象级别的一种可能性:您只需说明传递对象应该展示的能力(例如可排序性),而不是指定要求其参数成为某个类层次结构的一部分的方法。这通常允许您以更通用的方式制定算法。

答案 5 :(得分:0)

使用接口是一个OO范例。接口可以抽象实现,以实现更全面的测试,可伸缩性,并更轻松地构建基于组件(使应用程序更具可扩展性)的应用程序。

当然,接口的使用会根据需求而有所不同(例如,非功能性:必须能够为n层应用程序的每一层构建单元测试)。

多个开发人员可以在同一个应用程序上工作,而不关心其他开发人员如何实现他们的组件,但知道要发送什么以及再次发生什么。

基类与接口的一个优点是,您可以在特定层中的所有对象中共享功能(例如,对于分层体系结构)。例如。验证公共字段或转换常用数据类型。

答案 6 :(得分:-1)

接口编程是核心OO原则。它使您能够构建Dependency inversion/inversion of control - 即实现不直接依赖于其他实现 - 相反,它们依赖于其他类型。这样做可以很容易地插入/插入系统的部分。它还增强了系统的可测试性,因为如果您的所有实现都关心接口,它很容易提供符合接口的模拟。 此外,根据几个界面描述系统也可以更容易理解系统的整体策略。试图从一堆具有实现细节的基类中划分它,这使得它变得更加困难。

抽象基类实际上只是一种共享多个子类之间通用的实现的方法。但要注意避免接口并直接绑定到抽象基类 - 你正在做的事情是,你不仅要绑定到抽象基础的接口,还要总是随身携带实施。很多时候,今天看起来如此的东西在几个月/几年内就会转变180度,而这种“永久性”的决定是你不应该掉以轻心的。在我看来,总是有一个界面的成本要少得多。

因此,实际上,有一个接口来记录 Type ,如果在类型的实现者中你看到很多潜在的代码重用,那么创建一个从接口继承的抽象基。抽象基础还可以引入纯虚拟钩子方法,这些方法实际上是实现细节,并提供方便和代码重用。

最后,如果你的界面不正确,你可能会感到沮丧 - 在这种情况下,他们只会让事情变得更难(即你拥有所有额外的界面工作而没有任何优势,然后他们感到完全错误) - 但是由你说的是,这看起来并非如此。

完全披露 - 我不是.NET开发人员。我是一个java / python开发人员,虽然我有很好的接触.NET。我的工作场所的.NET开发人员远远多于Java开发人员 - 我们对这些讨论的讨论相当多。顺便说一句,我发现这种情况认为界面过度使用在.NET世界中比在Java开发中更普遍 - 但这只是我的观点。