C# - 系统地添加一个接口是一个好习惯吗?

时间:2010-07-01 12:27:44

标签: c# interface

在我正在研究的项目中,我注意到每个实体类都有一个接口。似乎最初的动机是仅将接口暴露给其他项目/解决方案。

我发现这完全没用,我没有看到为每个类创建一个接口的重点。顺便说一句,这些类没有任何方法只是属性,并且它们没有实现相同的接口。

我错了吗?或者这是一个好习惯吗?

THX

9 个答案:

答案 0 :(得分:7)

我倾向于为几乎每个类创建一个接口,主要是因为单元测试 - 如果你使用依赖注入并希望单元测试依赖于所讨论的类的类,那么标准的方法是模拟一个实例。有问题的类(使用其中一个模拟框架,例如Rhino-Mocks)。但是,实际上它只能用于接口,而不是具体的实现(是的,理论上你可以模拟一个具体的类,但是有很多痛苦的限制)。

答案 1 :(得分:6)

设置可能比此处描述的更多,这证明了接口的开销。通常它们对于依赖注入和关注点的整体分离,单元测试和模拟等非常有用。尽管它们在您的环境中不会被用于此目的(或任何其他建设性目的),但完全有可能。

这是生成的代码,还是手动创建的?如果是前者,我怀疑生成它们的工具是这样做的,如果开发人员如此倾向于准备这样的用途。如果是后者,也许最初的设计师会想到一些东西?

对于我自己的“最佳实践”,我几乎总是进行界面驱动的开发。将问题彼此分开并将接口用作它们之间的契约通常是一种很好的做法。

答案 2 :(得分:5)

公开公开接口有助于创建松散耦合的行为驱动架构。

为每个类创建一个接口 - 特别是如果接口只暴露了该类在单个接口中的每个公共方法 - 是一个糟糕的概念实现,并且(根据我的经验)导致更复杂的代码并且没有改进架构。

答案 3 :(得分:4)

它对测试很有用。

方法可以采用ISomething类型的参数,它可以是SqlSomething或XmlSomething,其中ISomething是接口,SqlSomething和XmlSomething是实现接口的类,具体取决于您是否正在进行测试(通过XmlSomething)在这种情况下)或运行应用程序(SqlSomething)。

此外,在构建可以在任何数据库上工作但不使用LINQ等ORM工具的通用项目时(可能因为数据库引擎可能不支持LINQ to SQL),您可以使用以下方法定义接口在应用程序中使用。稍后,开发人员将实现接口以使用数据库,创建MySQLProductRepository类,PostgreSQLProductRepository类,它们都继承相同的接口,但具有不同的功能。

在应用程序代码中,任何方法都会将参数作为IProductRepository类型的存储库对象,它可以是任何东西。

答案 4 :(得分:1)

如果这些类只有属性,那么接口不会增加太多的值,因为没有被抽象的行为。

接口可用于抽象,因此可以在单元测试中模拟实现。但是在设计良好的应用程序中,业务/域实体应该没有什么理由可以被嘲笑。另一方面,业务/域服务是接口抽象的理想选择。

我为我的实体创建了一次接口,它根本没有添加任何值。它只让我意识到我的设计是错误的。

答案 5 :(得分:1)

恕我直言,听起来毫无理由地编写接口毫无意义。你不能完全封闭,但总的来说做一些不是立即有用的东西往往会积累成废物。

其中既有增值又有价值的敏捷概念。

删除它们会发生什么?如果没有,那么......他们在那里做什么?

作为旁注。接口对Rhino Mocks,依赖注入等非常有用......

答案 6 :(得分:1)

它似乎是一个优于抽象基类的接口,主要是当/当需要有一个实现接口但继承自其他基类的类时。不允许多重继承,但多个接口实现是。

我看到使用接口而不是抽象类(超出所需的额外源代码)的主要警告是,更改接口中的任何内容都需要重新编译使用该接口的任何和所有代码。相反,将公共成员添加到基类通常只需要重新编译基类本身。(*)

(*)由于处理扩展方法的方式,向类添加成员不会“要求”重新编译使用该类的代码,但可能导致使用类上的扩展方法的代码在下次更改含义它(扩展方法使用代码)被重新编译。

答案 7 :(得分:1)

没有办法告诉未来,看看你是否需要在接下来的路线上编程。但是,如果您稍后决定使用一个接口,比如一个工厂来创建未知类型的实例(任何实现该接口的类型),那么将每个人限制为针对接口和工厂的前端进行编程会更快而不是稍后用IMyInterface等引用替换对MyImpl的引用

因此,在编写新软件时,除非您熟悉基于以往经验的软件可能会发生什么,否则判断是否要对接口或实现进行编程。

无论我是否有接口,基类或两者兼而有之,我通常都会“保持不变”,甚至基类都是抽象的(通常是)。在重构和/或要求第二意见之前,我将在一个项目(通常是一个包含大约3到10个项目的Visual Studio解决方案)上工作一段时间(可能是几天)。一旦做出最终决定并对代码进行重构和测试,我告诉其他开发人员它已经可以使用了。

答案 8 :(得分:0)

对于单元测试,它可以是任何地方的接口,也可以是虚拟方法。

有时我会想念Java:)