文档章节

关于依赖反转(基于接口编程)和依赖注入的一个小问题的领悟

猪刚烈
 猪刚烈
发布于 2014/10/12 11:40
字数 1235
阅读 36
收藏 0

行业解决方案、产品招募中!想赚钱就来传!>>>

  这两天学习设计模式,看到了关于依赖反转方面的东西,就依赖反转而言简单来说就是:软软设计存在抽象层和实现层之分,一般情况下是抽象依赖于实现,这很容易理解,但是问题在于抽象层相对稳定,实现层容易变化,抽象层应该具有较实现层更高的复用性,它就应该我们设计和考量的核心与重点,而不是具体的实现,这样一来,要求我将依赖关系反转过来,即实现应该依赖于我们的抽象,这样的设计才是灵活和易于扩展的。如此一来,依赖反转的概念就出来了,但是如果实现依赖反转呢?答案听上去是很简单的那就是基于接口进行编程,关于这一点在许多讲述设计模式的书中都有所介绍,接口是对类和方法的一组需求定义,由于接口不提供任何实现,它是一种最纯的抽象,基于接口进行编程可以真正意义上实现在抽象层上进行工作。但是还有一个恼人的小问题:

interface IService

{

 public void doSomething();

}

class ServiceImpl implements IService

{
 public void doSomething()
 {
  // do something......
 }
}

class Component
{

private  IService service=new ServiceImpl(); //这里是基于接口进行编程,但却在构造时与具体的实现发生了耦合

//后继方法中会使用该service

}

问题就出在对service的实例化上,我们可以明确的看到接口service在实例化时要不可避免地使用到它的实现类,从而导致了 service至少在创建时刻对具体实现产生了依赖,这使得我们之前打算的基于接口进行编程的工作似乎功亏一篑。在一些设计模式的书中对于这一问题的解决方法是使用工厂模式,来实现对service实例化的封装。

  呵呵,写到这里禁不住要偷笑了,因为晚上在思考这个问题的时候实然想到了spring的依赖注入,不禁恍然大悟:不需使用什么工厂模式,运用spring的依赖注入会完美地解决“抽象在创建时刻对实现产生依赖”的问题,在我们代码里,抽象将永远不需要再被指向他的具体实现了,这个过程会放到sping 的配制文件里,使用依赖注入的方式完成,这样了,我们真得就可以完美使用接口进行编程了!

 

 

以下内容是2010-5-8的补充:

 

     在我刚开始接触spring和IOC理论时,最常见的IOC示例就是Service依赖DAO时,在Service的实现类里声明一个DAO字段,通常这个DAO是一个接口,然后提供一个setter,就在Service的方法中开始使用这个DAO了,整个Service没有实例化这个DAO的操作。其实这个示例展示了两点:一个是依赖注入,另一个是基于抽象编程。我当时一直认为:只有在基于抽象编程的前提下,进行依赖注入才是有意义的。否则声明的是一个具体类,再注入一个具体类有什么意义呢?这是我三年前对IOC的认识。

    后来,我研究一个IOC框架PicoContainer:http://www.picocontainer.org/,这个IOC构架的参考文档让我对IOC有了更进一步的认识,也使我发现了我过去对IOC认识的一个局限。本质上讲,IOC之所以如此重要,是因为它解决了OO技术中一个重要的缺失:如何合理地创建对象并将它们关联起来协同工作。面向对象技术注重于对对象属性与行为的模拟,对这些对象从何而来,怎样相互依赖缺乏合理的模拟机制。很多时候,当一个对象A依赖到另一个对象B时,我们就new一个B的实例出来。这样做在有些时候是合理的,有些时候就是不恰当的。上面提及的基于抽象编程时就是一种情况。还有其他的情况。比如:A有没有创建B的责任?如果A没有创建B的责任,那么就不应该让A来承担。这是OO设计的一个重要原则:Designing Objects with Responsibilities。关于这一点,《Applying UML and Patterns, 3rd Edition》一书17.10节有详尽的说明。

   总之IOC就像一个系统的对象容器和粘合剂,它负责创建对象的实例,并按照它们声明的依赖关系把它们粘合起来共同工作。

猪刚烈

猪刚烈

粉丝 22
博文 708
码字总数 110
作品 1
海淀
程序员
私信 提问
加载中
请先登录后再评论。
Netty那点事(三)Channel与Pipeline

Channel是理解和使用Netty的核心。Channel的涉及内容较多,这里我使用由浅入深的介绍方法。在这篇文章中,我们主要介绍Channel部分中Pipeline实现机制。为了避免枯燥,借用一下《盗梦空间》的...

黄亿华
2013/11/24
2W
22
访问安全控制解决方案

本文是《轻量级 Java Web 框架架构设计》的系列博文。 今天想和大家简单的分享一下,在 Smart 中是如何做到访问安全控制的。也就是说,当没有登录或 Session 过期时所做的操作,会自动退回到...

黄勇
2013/11/03
3.4K
6
beego API开发以及自动化文档

beego API开发以及自动化文档 beego1.3版本已经在上个星期发布了,但是还是有很多人不了解如何来进行开发,也是在一步一步的测试中开发,期间QQ群里面很多人都问我如何开发,我的业余时间实在...

astaxie
2014/06/25
2.7W
22
Nutch学习笔记4-Nutch 1.7 的 索引篇 ElasticSearch

上一篇讲解了爬取和分析的流程,很重要的收获就是: 解析过程中,会根据页面的ContentType获得一系列的注册解析器, 依次调用每个解析器,当其中一个解析成功后就返回,否则继续执行下一个解...

强子哥哥
2014/06/26
712
0
树莓派(Raspberry Pi):完美的家用服务器

自从树莓派发布后,所有在互联网上的网站为此激动人心的设备提供了很多有趣和具有挑战性的使用方法。虽然这些想法都很棒,但树莓派( RPi )最明显却又是最不吸引人的用处是:创建你的完美家用...

异次元
2013/11/09
5.4K
8

没有更多内容

加载失败,请刷新页面

加载更多

如何使用pip升级所有Python软件包? - How to upgrade all Python packages with pip?

问题: Is it possible to upgrade all Python packages at one time with pip ? 是否可以通过pip一次升级所有Python软件包? Note : that there is a feature request for this on the off......

法国红酒甜
12分钟前
0
0
活体检测+合成图鉴别面前,人脸“照片活化”黑产攻击一秒被擒

本文作者:y****n 如今,随着人脸技术的日趋成熟,新兴娱乐文化得到了极大的推动,尤其是随着 DeepFake、FaceSwap 等人脸编辑及生成技术的发展,虚拟主播、人脸合成带给人们全新的体验,但同...

百度开发者中心
昨天
0
0
如何在SQL Server中将多行文本合并为单个文本字符串?

问题: Consider a database table holding names, with three rows: 考虑一个包含名称的数据库表,该表具有三行: PeterPaulMary Is there an easy way to turn this into a single str......

富含淀粉
42分钟前
9
0
在JavaScript中生成特定范围内的随机整数? - Generating random whole numbers in JavaScript in a specific range?

问题: 如何可以生成两个指定的变量之间的随机整数在JavaScript中,例如x = 4和y = 8将输出任何的4, 5, 6, 7, 8 ? 解决方案: 参考一: https://stackoom.com/question/6PRz/在JavaScript中...

fyin1314
今天
8
0
Vim清除最后一个搜索突出显示 - Vim clear last search highlighting

问题: Want to improve this post? 想要改善这篇文章吗? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. 提供此问题......

技术盛宴
今天
23
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部