为什么.NET应用程序中大量使用接口?

为什么.NET应用程序中大量使用接口?,.net,architecture,coding-style,.net,Architecture,Coding Style,最近,我开始着手一个大型主流项目,为一个我无法透露的客户提供一个面向公众的电子商务平台 我与经验丰富的开发商合作,他们在伦敦金融城的许多项目中都有多年的经验 似乎每个人都非常喜欢界面。这是压倒性的,我现在怀疑我以前所做的一切,也就是使用抽象基类 NET不是COM,它不是基于接口的编程平台。是我遗漏了什么,还是这只是从众心理——多年的编程已经成为.NET领域公认的标准 谢谢 Luke使用接口在很大程度上是一种面向对象的范例。接口可以抽象实现,以允许更全面的测试、可伸缩性和更容易构建基于组件(这使应

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

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

似乎每个人都非常喜欢界面。这是压倒性的,我现在怀疑我以前所做的一切,也就是使用抽象基类

NET不是COM,它不是基于接口的编程平台。是我遗漏了什么,还是这只是从众心理——多年的编程已经成为.NET领域公认的标准

谢谢


Luke

使用接口在很大程度上是一种面向对象的范例。接口可以抽象实现,以允许更全面的测试、可伸缩性和更容易构建基于组件(这使应用程序更具可扩展性)的应用程序

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

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


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

这完全取决于你想要实现什么。接口和抽象类之间的主要区别在于,一个类可以继承多个接口,但只能继承一个抽象类。因此两者都有各自的目的。

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


当然,当不同的实现之间有共同的功能时,您可以使用抽象基类(如果您愿意,还可以在抽象类之上有一个接口),但是如果抽象类中的所有内容都是抽象的,并且没有字段,为什么要通过抽象类来使用一次性继承呢?好处在哪里?

抽象类和接口有两种不同的用途。
第一个用于提供父/子继承。
第二个用于指定实现类的特定行为。
我同意界面被频繁使用的原因是错误的

编辑:
此外,大量使用接口可能会导致装箱/拆箱问题:

当实现接口的值类型被传递给以接口类型为参数的方法时,可能会发生这种情况。我个人不得不面对这个问题,并重构代码以摆脱接口(尽管对于API来说这很方便)以获得性能,因为问题类在运行时被使用和传递了数百万次。

接口指定类型的功能,而不是继承关系。接口的“好”示例是那些封装了相当一般的概念的接口,这些概念可能适用于范围广泛的非常不同的具体类型,这些类型可能没有其他共同点(想想
IComparable
IEnumerable


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

抽象和接口有其不同的用途

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

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

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

另一方面,接口只是定义您期望实现类做什么,而不是完全类似。对于如何实现这些能力,没有明确的定义。事实上,这些实现可以很好地为主系统实现完全不同的功能,但是以模板化的方式(接口)构建,以允许系统以标准的方式管理它们


e、 IHttpModule、Providers、System.Runtime.Remoting.Channels等。

接口编程是OO的核心原则。它使您能够内置
依赖项反转/控制反转
——ie实现不直接依赖于其他实现,而是依赖于其他类型。这样做的目的是便于插入/拔出系统的某些部分。它还增强了系统的可测试性,因为如果您的实现只关心接口,那么很容易提供符合接口的模拟。 此外,通过几个接口描述系统也可以更容易地理解系统的总体策略。试图从一堆具有实现细节的基类中发现这一点只会让事情变得更加困难

抽象基类实际上只不过是一种在多个子类之间共享实现的方法。但是要小心避免接口和直接绑定到抽象基类——这是您所做的