Java 当只有一个具体类时(编程到使用具体类的接口v/s)

Java 当只有一个具体类时(编程到使用具体类的接口v/s),java,oop,design-principles,Java,Oop,Design Principles,在OO组件中,当一个类只有一个实现可用,而该类没有“发布”到其他组件时,是否仍然建议使用接口并使用该接口 我完全了解“编程到接口”的设计原则,并广泛使用它 最近,我一直注意到,大多数时候,根本不需要一个不同的实现(尽管可能而且有意义)。由于总是使用接口,应用程序代码将有相当数量的接口,每个接口只有一个实现,并且接口似乎有点开销 相反,只使用具体类并仅在需要第二个实现时引入接口是否更可取?无论如何,现在使用IDE提取接口是轻而易举的事。当引入新接口时,可以将对旧具体类的引用更改为使用新接口 您认为

在OO组件中,当一个类只有一个实现可用,而该类没有“发布”到其他组件时,是否仍然建议使用接口并使用该接口

我完全了解“编程到接口”的设计原则,并广泛使用它

最近,我一直注意到,大多数时候,根本不需要一个不同的实现(尽管可能而且有意义)。由于总是使用接口,应用程序代码将有相当数量的接口,每个接口只有一个实现,并且接口似乎有点开销

相反,只使用具体类并仅在需要第二个实现时引入接口是否更可取?无论如何,现在使用IDE提取接口是轻而易举的事。当引入新接口时,可以将对旧具体类的引用更改为使用新接口


您认为呢?

为具体类型创建接口是一个微妙的平衡行为,因为您可以轻松创建一个接口爆炸,它没有任何好处,只会使用冗余类型使域空间复杂化


我的经验法则是只为属于面向公共API的类型创建接口。所有专用于API实现且从未从API中公开的类型都不需要接口。

即使只有一个实现,我仍继续对接口编程的一个原因是它使编写测试变得更加容易。我可以设置代理来测试我想测试的任何东西,我不必担心紧密耦合

这并不总是明智的,但当你试图做出决定时,这是值得考虑的。你认为你需要围绕这个类/对象进行广泛的测试吗?如果您认为您会这样做,那么与具体类相比,处理接口会容易得多


另一种选择是不使用接口,不使用具体类的子类,这也是可行的,但这取决于具体类。

接口应该是进化的,而不是创建的。在创建接口之前,您应该对接口有特定的需求。如果您不需要多个实现,则不需要接口。始终记住,

据我所知,有三种情况下接口是合理的:

  • 它是架构的一部分(我承认这一部分的定义不是很好)
  • 您有多个实现
  • 这是一个公共界面
  • 不要害怕使用具体的类。
    不要机械地为每一个类生成一个接口。

    除了已经给出的好答案(易于测试和公共API)之外,我喜欢使用接口,因为它更容易关注类应该做什么而不是如何做他们正在这样做。

    一般来说:不需要。如果只实现一次功能,就不需要接口。
    像任何东西一样的接口都有一个折衷:它们会带来更多的工作(成本),并且可能会带来更多的好处。如果成本大于收益,你可能不应该这么做

    +1 b/c当从不使用接口转移到使用接口时,如果它是您的公共API的一部分,并且您已将代码发布给外部用户,则很可能是不可能的。同意,我最近一直在讨论“什么是最可测试和可重复的解决方案”?考虑到这一点,我的代码库变得更加简单,同时在最重要的方面,接口也非常受驱动。EasyMock和JMock都支持类模拟,因此测试参数是无声的。这会让你陷入接口地狱。如果不需要声明方法final,可以使用easymock的类扩展。如果这不是一个选项,您可以使用powermock。今天,没有理由仅仅为了简化测试而添加接口。至少在上面提到的情况下没有。如果你在界面地狱中,你可能没有使用ReSharper。实施使痛苦消失。:)与“转到实现”解决的问题相比,接口地狱有更多的问题。添加公共方法意味着在两个位置添加它。你需要申报两次而不是一次,这是浪费。除此之外,接口的存在表明实现类有一个角色,未来的开发人员可能会质疑新添加的公共方法是否应该是该角色的一部分。我同意。只要记住在开发时给你的客户戴上帽子——如果你的类会被其他人使用,如果你不提供接口,他们会诅咒你。您可能不需要它,但如果类有任何重要的功能/依赖项,它们就会需要它。@SingleShot同意,这取决于您正在编写的软件类型。很多“应用程序”软件都不是由外部参与者编写的-