论坛首页 Java企业应用论坛

面向接口编程的思考

浏览 3992 次
精华帖 (0) :: 良好帖 (6) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-05-18  

      随着IOC各种实现(比如Spring /guice )出现,特别是Spring的影响力的扩大化,面向接口编程范式被提出来,于是企业编程中便大量地使用IOC技术,典型的展现形式是一个接口对应一个(几乎全部是仅有一个 )实现,接口和具体的实现类的绑定通过IOC容器实现。相信这种现象很多人都看到过,并且现在依然在这么做,甚至没有停下来思考过合理性。我记得刚刚进入公司的时候,看到应用中有大量的spring配置文件,各种DAO和各种Manager都配置在其中,而且几乎每个接口基本都是只有一个实现类。我尝试怀疑过这样做的合理性,但是被“资深人士”解说,“这是面向接口编程范式,只依赖接口,可以隐藏实现细节,隔离实现类使用的依赖,适应新的变化。 ”类似的话,然后我崇拜地点了点头,表示恍然大悟,其实我并没理解

     现在回过头来看看,这些话是不是真的名副其实呢?“只依赖接口,可以隐藏实现细节”这句话,我表示赞同,但是这不是使用接口的有力证据。事实上,类(class)本身也是对功能的抽象,也隐藏了实现细节。“隔离实现类使用的依赖”这句,我表示不完全苟同。举例说明,假如A是接口,AImpl是A接口的实现类,B是A的客户端,如果B直接依赖AImpl的话,会把AImpl依赖间接依赖进来,但是是编译时依赖。如果B依赖A接口,那么最终在运行时AImpl最终会被注入到B中,顺带着AImpl的依赖会带进来,不过这个是运行时依赖。通过这个,不难看出,只是把依赖搞成了编译时和运行时,当然运行时的依赖有时候会好点,比如通过OSGi 可以暴露出很少的类,从而减少依赖冲突。再来看“适应新的变化”这句,前边也说到,几乎每个接口都只有一个实现类,那么貌似适应新的变化并不具备说服力。当然,我并不是完全否定面向接口技术,也不是对IOC嗤之以鼻。我只是想表达一下“一个接口一个实现”的问题。

      接下来,什么时候情况下才考虑使用面向接口技术呢?要搞清楚这个,首先谈下接口的意义。个人理解如下:接口是对功能的抽象,更是对功能变化 的抽象;接口是模块间 的一种契约。接口这两点特性决定了接口的使用方式, 对于独立的模块(甚至是独立的系统)之间的交互,使用接口是推荐的方式,甚至是必须的 ,这样隔离了模块实现细节,对模块之间的独立开发重构以及测试都起到了关键作用。 对于模块内部那些经常变化(至少目前业务可见范围内)的功能单元,可以抽象成接口 ,这样方便以后提供新的实现类来增加新的功能,这个不是必须的,但是是推荐的。 对于模块内部几乎不会发生变化的功能,就没有必要提供抽象成接口了 ,因为很少变化,而且是在模块内部使用,所以以Class的形式抽象就完全可以了。



 
 如上图,蓝色区域代表一个模块甚至是一个系统,黑色条带表示接口,黄色表示具体的功能类,绿色区域表示实现了接口的功能类,箭头表示依赖或者实现接口。这幅图基本描述了,接口的使用方式,模块之间使用接口依赖,模块内部多变功能使用接口抽象,模块内部很少变化的功能不使用接口

      好吧,就这么多吧。第一次写技术博客,个人的理解和高度有限,难免会有误差,欢迎拍砖。

                                                                                                                                         

  • 大小: 22.9 KB
   发表时间:2012-07-06  
这个就是所谓的过度设计了。
0 请登录后投票
   发表时间:2012-07-06  
请搜索 跟着cc学设计 获取最新的设计技术资料
0 请登录后投票
   发表时间:2012-07-07  
说下我个人的观点:
1、OO设计要求只暴露必要的接口,比如说如果你不需要别人来set数据或者别的对象,那么不需要提供set方法。
2、Spring常用的注入方式是set,那么与上面的设计要求相背,所以即使只有一个实现类,也最好有个接口,这个实现类中用来支持注入。至于通过构造函数注入,也是一样的。
0 请登录后投票
   发表时间:2012-07-07  
这里有个误区,你理解的spring不够深入。当你从组件角度来看的时候你就明白什么时候要接口什么时候不要了。spring的问题在于组件粒度太小,所以你会感觉到“漫天飞接口”。这是“框架使用问题”,不是“框架设计问题”。
0 请登录后投票
   发表时间:2012-09-18  
我觉得楼主说得挺好,尤其是最后一段
0 请登录后投票
   发表时间:2012-12-12  
fireflyc 写道
这里有个误区,你理解的spring不够深入。当你从组件角度来看的时候你就明白什么时候要接口什么时候不要了。spring的问题在于组件粒度太小,所以你会感觉到“漫天飞接口”。这是“框架使用问题”,不是“框架设计问题”。

貌似咱们的观点并不矛盾,我说的模块和你想表达的组件是一个概念,可以理解为一个组粒度的功能单元,由多个bean组合起来实现的,就模块内部的实现,每个小的功能点不一定要抽成接口,这是我所表达的意图。
0 请登录后投票
   发表时间:2012-12-12  
kyfxbl 写道
我觉得楼主说得挺好,尤其是最后一段

那请高手教教我?我最后一段好在哪儿?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics