依赖注入及AOP简述(一)——“依赖”的概念 .
一、入门:依赖注入
作为一种全新的设计模式理念,“依赖注入”这个词汇在软件设计开发中已经是越来越耳熟能详了,而各种流行于开源社区的“依赖注入框架”,也越来越多的被当作软件工程开发过程中使用的基础框架。这一章我们主要介绍什么是依赖注入、它的来源是什么、以及能给我们带来什么样的好处。
1. “依赖”的概念
要了解依赖注入,我们首先需要了解什么是“依赖”。从现实世界的观点来看,“依赖”即某个实体对象为了完成某项功能,必须要依托另外一些实体对象,那么这些被依托的实体对象即被称为“依赖”(Dependency),而依托其它“依赖”从而完成某项功能的对象,往往被称作“依赖者”(Dependent)。看似有些晦涩难懂,但用我们平常使用的Java语言来讲,其实很简单,所谓“依赖”,用最浅显的话说,就是我们平常写一个Java类中所定义的成员变量。(注:严格来说,还有把方法参数作为“依赖”的情况,我们暂不讨论此例)
看一个很常见的场景的例子:某储户需要到银行去办理一笔取款业务。在这个场景中,该储户即为一个“依赖者”;那么其为了完成取款业务,则需要依托很多其它的实体对象,为简单起见,我们假设该储户仅需要一张存折和附近的一所银行,此处存折和银行则为“依赖”。翻译成Java语言去描述,则可写出如下的代码。
|
“依赖注入”的概念及其实践来源于Java的开源社区,但是这种理念亦可以应用到其它面向对象、并带有Garbage
Collection和反射机制的静态语言当中,例如C#。
2. 传统的组件耦合方式及其带来的问题
我们都知道,一个对象(依赖者)当中调用另外一个对象(依赖)的API,即组件间的耦合是面向对象语言开发过程中必然要遇到的问题。拿我们刚才的例子来说,储户类调用银行类就可以看作是储户与银行两个组件在相互耦合。但是刚才的那个例子是不能被主程序直接运行的,因为我们的bank依赖并没有被初始化,所以如果调用到了Depositor#withDraw则会出现NullPointerException(NPE)异常。
|
因此我们需要想办法得到一个“组装”好的Depositor类的对象。在依赖注入设计模式出现以前,通常有下面几种组件的组装方法,我们依次来讨论一下。
2.1. 手工组装模式
一种常见的组件耦合方式就是我们经常使用的“new”,即通过依赖类的构造方法new出一个新的对象作为依赖者类的初始化状态。
继续我们刚才的例子,在主程序能够new出依赖之前,首先我们要实现一个工商银行的银行类,以及一个工商银行的存折类。
|
之后我们便可以在Depositor类中利用这些实现类初始化出需要的依赖对象后,刚才的DepositMain就可以正常运行了。
|
这种手工new的组装方式,虽然是Java平台程序开发中最基本的方式,但是其会带给我们在开发、维护以及测试等方面带来极大的困扰。
l 还以刚才的取款场景为例,开发过程中,对于实现储户取款这个场景(Depositor)的开发者来说,需要关心的事情只是储户取了多少钱,而不应该为了调用取款的API而费尽心思地去创建Bank和DepositBook对象。我们这个例子是非常简单的,仅仅是为了说明方便所以将依赖的构造函数的参数设定为及其简单的Java基础类型,试想在现实的开发中,Bank和DepositBook依赖自身还将会有依赖,依赖中又有依赖,如果是这样一个极其复杂的依赖关系图(DependencyGraph),对于开发人员来讲构建组件将会是非常痛苦的一件事情!并且,如果在依赖关系图中的某一层中涉及到了诸如DataSource连接、硬件连接这样的依赖对象,开发人员一定会抱怨“这些对象与我在开发的功能完全没有关系”!
l 从代码维护的角度看,过多的用构造方法new出对象这种方式,对于代码变更的维护的成本也是巨大的。例如,我们的BankICBC实现类的构造参数发生了变更,比如需要追加一个“网点类型(分理处/支行/分行)”这样的参数,那么我们的代码中所有调用到BankICBC的地方都需要发生相应的修改及对应的回归测试!
l 最后我们谈到的一点,也是软件开发过程中极其关键的一点,即给单元测试带来的不便。例如在实际的单元测试过程中,“工商银行”类由于牵扯到实际环境以及难以构建复杂依赖图等原因我们没有办法直接使用,而想要自行在测试代码中实现一个Mock类来代替实际的“工商银行”类,比如MockBank,我们会发现这个MockBank类没有办法方便地替入到实际的Depositor#withDraw代码中去。单元测试往往是软件工程中自动化程度最高,回归测试成本最低的测试手段,如果没有良好的单元测试体系,软件工程的维护等是难以方便的运行的。
依赖注入及AOP简述(一)——“依赖”的概念 .的更多相关文章
- 依赖注入及AOP简述(三)——依赖注入的原理
3. “依赖注入”登场 于是诸多优秀的IT工程师开始想出了更加轻量便利.更加具有可测试性和可维护性的设计模式——IoC模式.IoC,即Inversion of Control的缩写,中文里被称 ...
- 依赖注入及AOP简述(十一)——生命周期管理 .
2. 生命周期管理 各种依赖注入框架提供了替开发者管理各种Scope的便利功能,随之而来的就必然是被管理的依赖对象的生命周期管理的问题.所谓生命周期管理,就是一个对象在它所属的Scope中从被 ...
- 依赖注入及AOP简述(十三)——AOP应用举例(完结) .
2. AOP应用举例 在一般的应用程序开发中,有一些典型的AOP应用,使得开发者可以专注于业务逻辑本身,而不是与之完全无关的一些“方面”. l 首先就是关于前面介绍过的日志输出类 ...
- 依赖注入及AOP简述(十二)——依赖注入对象的行为增强(AOP) .
四.依赖注入对象的行为增强(AOP) 前面讲到,依赖注入框架的最鲜明的特点就是能够提供受容器管理的依赖对象,并且可以对对象提供行为增强(AOP)功能,所以这一章我们来讨论有关AOP的话题. 1. ...
- 依赖注入及AOP简述(九)——单例和无状态Scope .
三.依赖注入对象的Scope及其生命周期 在前面的章节我们讲到,依赖注入容器之所以能够区别于以往的ServiceLocator等容器,是在于其不但能够自动构建多层次的.完整的依赖关系图,并且可以管理依 ...
- 依赖注入及AOP简述(七)——FQCN请求模式
2.2. FQCN请求模式 为了弥补纯字符串请求模式中的类型安全问题,全类名(FQCN)请求模式就应运而生了.其思想便是,在向容器请求依赖对象的时候,不是通过字符串的标识符.而是通过被请求的依赖 ...
- 依赖注入及AOP简述(六)——字符串请求模式 .
2. 依赖注入对象的请求模式 前一节我们讨论了关于声明注入点的几种方法,这一节主要来介绍在注入点上如何定位到所需要的标识符的话题.基本上,我们可以用字符串为标识符来请求依赖对象.或者用全类名( ...
- 依赖注入及AOP简述(五)——依赖注入的方式 .
二.依赖注入的应用模式 前面我们了解了依赖注入的基本概念,也对一些依赖注入框架进行了简单的介绍,这一章我们主要来讨论作为开发者如何利用依赖注入框架来实现依赖注入的设计思想. 1. 依赖注入的方 ...
- 依赖注入及AOP简述(四)——“好莱坞原则”和依赖注入框架简介 .
3.2. “好莱坞原则” 看了前面关于依赖注入概念的描述,我们来提炼出依赖注入的核心思想.如果说传统的组件间耦合方式,例如new.工厂模式等,是一种由开发者主动去构建依赖对象的话,那么依赖注入模 ...
- 依赖注入及AOP简述(二)——工厂和ServiceLocator .
2.2. 工厂模式 基于手工构建组件的诸多弱点,1995年“大师4人组”(GoF)在其经典著作<DesignPatterns>一书中提出了“工厂模式”,这种模式在一定程度上有效的解决 ...
随机推荐
- javax.Swing 使用GridBagLayout的程序栗子
摘自https://zhidao.baidu.com/question/110748776.html javax.Swing 使用GridBagLayout的程序栗子 总共两个文件,第一个是启动文件, ...
- grep, egrep, fgrep笔记
grep, egrep, fgrep grep: 根据模式搜索文本,并将符合模式的文本行显示出来.Pattern: 文本字符和正则表达式的元字符组合而成匹配条件 grep [options] PATT ...
- Android应用程序中的多个Activity的显示创建和调用
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTkzNjE0Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- ADO.net基础学习总结
ADO.net是一门.net连接.操作数据库的技术 释放资源:凡是实现了idisposable借口的类都需要用using来释放资源 using() { } 连接数据库 //创建数据库连接: usi ...
- VS插件集
Unit Test Generator 很好用的测试插件 注:在VS2015中,改名为Test generator Nunit extension了. ReSharperPlatformVs11 ...
- @page指令 validateRequest的作用
在 Web 应用程序中,要阻止依赖于恶意输入字符串的黑客攻击,约束和验证用户输入是必不可少的.跨站点脚本攻击就是此类攻击的一个示例.其他类型的恶意数据或不需 要的数据可以通过各种形式的输入在请求中传入 ...
- 给远程桌面发送“Ctrl+Alt+Delete”组合键
首先: 在运行里,输入osk, 打开软键盘 然后,这时先按下本地键盘的Ctrl和Alt键,再点远程"软键盘"的"Del"键,成功发送"Ctrl+Alt ...
- 【.NetRemoting-2】2015.09.17
[Remoting架构] [1]是.NetFramework的一个重要组成 [2]框架的两个重要特性 [A]基本实现[B]可扩展/可定制 [各个组成部分] [1][客户端,客户端应用程序域] [组成] ...
- noNamespaceSchemaLocation前添加xsi
在.Net中操作xml文档,给节点添加,xsi:noNamespaceSchemaLocation属性时,不可以使用 XmlElement eleRoot = doc.CreateElement(&q ...
- linux学习笔记之系统标准:POSIX,ISO C...
一.POSIX,ISO C,Single UNIX Specification的概念. 1,POSIX:Portable Operating System Interface.可移植操作系统接口.期望 ...