我是C#程序员。在我的上一份工作和当前的工作中,为我们编写的大多数类创建接口都是很常见的。例如。当我们有一个名为Spork的类时,我们将添加一个包含Spork的公共方法的接口ISpork。这些接口用于依赖注入(例如,通过StructureMap)和用于在单元测试中创建模拟(例如,使用Rhino Mocks或Moq)。
几周前,我参加了Javs开发人员的演讲。我们以某种方式谈论了接口,而他似乎真的很惊讶,任何人在类和接口之间都会有很多一对一的关系。
现在我的问题是:我多年来一直做错了吗?还是这是Java vs C#的事情?如果是这样,那么如何在Java中处理模拟和依赖注入?
P.S .:我主要对DI和模拟方面以及许多仅有一个实现类的接口的相关需求(或没有?)感兴趣。我认为情况已经改变。既不会被模拟也不会被注入的类非常相似。但是令我感到惊讶的是,对于C#开发人员来说,对于我来说,这似乎简直是轻而易举。
答案 0 :(得分:1)
依赖注入用于包含和分离关注点。您想在代码中做一些新的事情,添加一个依赖接口即可。然后,您可以测试代码,而无需再担心该接口的实现,直到稍后。
但是,您的问题是关于接口和实现之间的一对一关系。从我的角度来看,这是无关紧要的,因为您仅在已声明的接口的上下文中关心实现,而不在意使用它的位置。例如,您可以让一个类继承多个 injectable 接口,这通常表明它承担了太多责任,但是可以做到。您可以具有多个类,这些类继承相同的接口,然后基于DI配置使用。甚至在某些情况下,DI容器处理我通常转交给工厂的东西,主要是根据一些参数为您提供接口的实现。
无论哪种方式,这有什么关系?如果(减少到荒谬)每个类只有一个开发人员,那么他们将只编写其代码和测试,并定义所需依赖项的接口,让其他人来实现它们。
答案 1 :(得分:1)
DI只能与没有接口的类一起使用。您注册类型,然后注入类型。就这样。谈到单元测试中的模拟时,会有所不同。 在c#中,您只能模拟虚拟或抽象(也是虚拟的)成员。因此,如果您希望代码可测试,则需要在实现中使用virtual
关键字标记所有公共成员,或使用接口而不是真实的类。 在Java中,默认情况下所有方法都是虚拟的,因此它们不会对一一对应的界面造成麻烦,因为它们可以模拟所有内容。