Java中的接口优势
我的问题很简单:如果它们是由单个类实现的,那么使用接口是否有任何优势?
我一直认为只有当该接口有多个实现时,接口才是好的。
谢谢。
总之一句:不。 接口的合同可以直接在您的类中指定。
如果您明确表示将来不需要再使用相同方法,则可以避免定义接口。
当然,这里的问题是“未来”条款。 如果项目很小,没有很长的开发/升级期,并且定义明确,那么您几乎可以确定将来需要什么。
如果项目很长,可能会有变化,那么你将不得不考虑:
- 你最终需要一个接口的概率。
- 你现在知道接口将来需要什么方法的概率。
- 现在做界面的成本与未来的重构有关。
考虑到现在可能只有一个实现,但将来可能会出现更多的实现。 此外,通过使用接口,您可以通过仅使用接口来避免创建对具体类的依赖性。 然后,稍后,如果您决定更改实现,则可以创建一个实现接口的新实现,而不会对仅依赖于您的接口的其他代码产生不利影响。
考虑:
public interface SomeInterface {...} public class AConsumerOfSomeInterface { private SomeInterface service; public AConsumerOfSomeInterface(SomeInterface theImplementation) { service = theImplementation; } //some code which uses the service }
现在,您可以在未来更改此类的情况下交换实现。 因为这很容易做到,即使您认为不需要接口也很有意义。
接口是一种解耦单独软件组件的方法。 当然,您今天可以使用Oracle数据库存储所有数据,为什么不分配所有DAO接口?
答案是强烈耦合到任何东西可能会回来并在将来咬你。 如果明年你想使用一些云服务存储数据怎么办? 如果你编码为DAO接口,你可以简单地引入一个新的云实现并直接插入。你的应用程序松散耦合,所以不需要改变。
我想补充一点:接口有助于代理模式 。
在Web应用程序中,此代理对抽象有很大帮助。 我是Web应用程序的新手,但通常我通过接口设计我的服务层。 在使用Wicket构建的Web应用程序中,我有一个接口Afrodite
和一个AfroditeImpl
类作为服务层,从applicationContext初始化为spring bean。 然后我们可以获得Afrodite
定义的所有方法,并通过所有网页在Afrodite
实现
AfroditeApplication application = (AfroditeApplication)getApplication(); Afrodite afrodite = application.getAfrodite(); // Now call the service layer's methods by afrodite
大纲是:
public interface Afrodite { } public class AfroditeImpl implements Afrodite { } public class AfroditeApplication extends WebApplication { Afrodite afrodite; public Afrodite getAfrodite() { return afrodite; } @Override public void init() { super.init(); ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); afrodite = (Afrodite) applicationContext.getBean("afrodite"); } }
希望这可以帮助。
问问自己是否真的有可能在不久的将来有多个实施。
您可以在需要时轻松添加界面,有时还可以添加多个界面。
我为单个类创建接口的唯一情况是区分常用的API和专用API (测试,监控等)。
如果它们是由单个类实现的,那么使用接口是否有任何优势?
如果你的界面只由一个类实现,并且你100%确定你永远不会觉得需要添加另一个实现,那么没有任何优势。
无论如何,我认为还有另一种情况需要牢记。 假设您有一个类比您想要向另一个客户端类公开的更多。 可以使用接口来限制客户端可以调用的类的方法:
public interface clientInterface{ public foo(); public bar(); } public class yourClass implements clientInterface{ public foo(){} public bar(){} public doSomethingElse(){} } public class clientSideFactory{ public clientInterface getClass(){ return new yourClass(); } } public class internalSideFactory{ public clientClass getClass(){ return new yourClass(); } } }
在上面说明的情况中,即使您有一个接口clientInterface的单个实现(clientClass),这也很有用,可以返回到只能看到类的有限部分的客户端类(限制类完整实现的可见性) )。