个人学习笔记,来自Acode

1、术语

控制反转/反向控制,英文全称“Inversion of Control”,简称IoC。

依赖注入,英文全称“Dependency Injection”,简称DI。

据说是Martin Fowler对控制反转的原理进行了深入的探索后,为控制反转起了个新的名字叫“依赖注入”。也就是说,这两个术语讲的是同一个事物。

2、控制反转的“奥义”

  “实现必须依赖抽象,而不是抽象依赖实现”。

3、实例理解

  只看了控制反转的奥义,对于一般人来说还是难以理解,就好比一位功夫大师告诉我们“无招胜有招”,资质平平的我还是无法理解到大师们的话,于是就凌乱了...

  下面,还是通过实际的程序来理解一下控制反转。

假设场景:从SQL Server数据库中获取数据。

【普通方法】

一般人会这么写程序:

首先,实现一个对数据库进行各种操作的类SqlServerDataBase:

 /*
*SqlServerDataBase.java
**/ public class SqlServerDataBase { /*
*构造函数、数据库连接等操作对应的语句
*/ //从SQL Server数据库中获取数据
public List getDataFromSqlServer() {
//获取数据的具体语句
}
}

然后,就可以在业务层通过对象的实例来获取需要的数据:

 /*
*Business.java
**/ public class Business{
private SqlServerDataBase db = new SqlServerDataBase(); //从SQL Server数据库中获取数据
public void getData() {
List list = db.getDataFromSqlServer();
} }

这么一看,感觉代码写得很不错啊,完美地满足了需求。可是,某一天,决定要将数据库更换为MySQL,于是我们历尽千辛万苦写的两个程序都不能用了,我们需要重写下面的代码:

/*
*MySQLDataBase.java
**/ public class MySQLDataBase { /*
*构造函数、数据库连接等操作对应的语句
*/ //从MySQL数据库中获取数据
public List getDataFromMySQL() {
//获取数据的具体语句
}
} /*
*Business.java
**/ public class Business{
private MySQLDataBase db = new MySQLDataBase(); //从MySQL数据库中获取数据
public void getData() {
List list = db.getDataFromMySQL();
} }

我们又费劲巴拉地写了上面的两个文件。这时,客户又决定要用Oracle作为数据!!!这时,估计你的内心是无比的崩溃的。为了毛爷爷,我们忍了,再次写了新的程序。

当写了以Oracle为数据库的程序后,客户说要用MongoDB作为数据库!!!这时,感觉再也不要当程序员了。

总结:

  从上面的例子中可以看出,一旦客户的业务需求变了,我们写的代码基本就白搭了,还要重写新的代码。这是为什么呢?原因是:Business类的中使用到了具体的数据库对应的类,一旦要使用的数据库改变了,Business中的代码也得跟着改啊(getDataFromSqlServer()->getDataFromMySQL()->...)。

教训:

  要实现一种代码可以多次重复利用,不依赖于具体业务的代码,实现Business类的重用。这时,我们想到了大神告诉我们的控制反转的奥义“实现必须依赖抽象,而不是抽象依赖实现”。

【IoC方式实现】

1、首先,定义一个从数据库中获取数据的接口DataBase,作为一个接口,它里面只有方法的声明,此处我们需要一个从数据库中获取数据的方法:getData()。

 /*
*DataBase.java
*/ public interface DataBase{
//该方法用来获取数据
public void getData();
}

2、接着,此时客户要求采用SQL Server作为项目的数据库,那么就实现一个负责从SQL Server数据库中获取数据的类SqlServerDataBase:

 /*
*SqlServerDataBase.java
*/ public class SqlServerDataBase implements DataBase{
//该方法用来获取数据
public void getData() {
//以下是具体从SQL Server数据库中取数据的代码
......
}
}

该类具体实现了从SQL Server数据库中获取数据的过程。

3、此时,业务需要从数据库中获取数据,实现业务类Business(注意该类的写法,很重要):

 /*
*Business.java
*/ public class Business {
//针对接口DataBase定义变量
private DataBase db; public void setDataBase(DataBase db) {
this.db=db;
} //根据注入的数据库类,从xxx数据库中获取数据
public void getData() {
db.getData();
}
}

注意的地方:

  (1)在第7行,定义了一个操作数据库的接口的变量db,并不是依赖于具体实现的类的变量;

  (2)定义了setDataBase()方法,该方法实现了具体实现的数据库操作类的变量的注入;

  (3)getData()方法或根据实际注入的数据库类型获取数据。

总结:

  可以看出,该方法的实现是依赖于抽象,而非依赖于具体的实现,是不是想到了IoC的终极奥义“实现必须依赖抽象,而不是抽象依赖实现”。

4、通过3中的Business类,实现了代码的重用(个人感觉,也就是对业务层也实现了“兼容性强的一种封装”,因此才实现了代码的重用),下面就看一下怎么根据具体的数据库类型来实现数据库的取数据:

 /*
*TestBusiness.java
*/ public class TestBusiness {
private Business Business = new Business(); //根据注入的数据库类,从SQL Server数据库中获取数据
public void getData() {
business.setDataBase(new SqlServerDataBase());
business.getData();
}
}

在第10行中,我们将SQL Server类的变量的注入到业务类Business中,也就实现了从SQL Server数据库中取数据的操作。此时,我们就再也不怕客户更换数据库了。

假设客户要采用MySQL作为数据库,那么,我们需要做的只有两点:

(1)实现基于MySQL的取数据的类MySQLDataBase

 /*
*MySQLDataBase.java
*/ public class MySQLDataBase implements DataBase{
//该方法用来获取数据
public void getData() {
//以下是具体从MySQL数据库中取数据的代码
......
}
}

(2)更改注入的数据库类型

 /*
*TestBusiness.java
*/ public class TestBusiness {
private Business Business = new Business(); //根据注入的数据库类,从MySQL数据库中获取数据
public void getData() {
business.setDataBase(new MySQLDataBase());
business.getData();
}
}

我们只需要更改第10行中药注入的数据库类型,就完成了所有的工作。

此时,再次理解下IoC的终极奥义:实现必须依赖抽象,而不是抽象依赖实现。(修炼的境界又提升了一层)

转载请注明出处:http://www.cnblogs.com/acode/p/5356686.html

控制反转(IOC)/依赖注入(DI)理解的更多相关文章

  1. spring(3)------控制反转(IOC)/依赖注入(DI)

    一.spring核心概念理解 控制反转: 控制反转即IoC (Inversion of Control).它把传统上由程序代码直接操控的对象的调用权交给容器.通过容器来实现对象组件的装配和管理. 所谓 ...

  2. 依赖倒置原则DIP&控制反转IOC&依赖注入DI

    依赖倒置原则DIP是软件设计里一个重要的设计思想,它规定上层不依赖下层而是共同依赖抽象接口,通常可以是上层提供接口,然后下层实现接口,上下层之间通过接口完全透明交互.这样的好处,上层不会因依赖的下层修 ...

  3. Spring 之 控制反转(IoC), 依赖注入(DI)和面向切面(AOP)

    关于依赖注入, 这篇博文写的非常简单易懂. https://github.com/android-cn/blog/tree/master/java/dependency-injection 此外, 博 ...

  4. 对spring控制反转以及依赖注入的理解

    一.说到依赖注入(控制反转),先要理解什么是依赖. Spring 把相互协作的关系称为依赖关系.假如 A组件调用了 B组件的方法,我们可称A组件依赖于 B组件. 二.什么是依赖注入. 在传统的程序设计 ...

  5. java 控制反转和依赖注入的理解

    开始好好学习java基础和思想~ 控制反转(IOC)是Spring框架的核心思想,用我自己的话说,就是你要做一件事,别自己可劲new了,你就说你要干啥,然后外包出去就好~ 依赖注入(DI) 在我浅薄的 ...

  6. Spring理论基础-控制反转和依赖注入

    第一次了解到控制反转(Inversion of Control)这个概念,是在学习Spring框架的时候.IOC和AOP作为Spring的两大特征,自然是要去好好学学的.而依赖注入(Dependenc ...

  7. 控制反转和依赖注入(对IOC,DI理解+案例)

    理解 控制反转说的官方一点就是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其实就是一种设计思想,大概思想就是把设计好的对象交给容器控制,而不是在你内部直接控制. 依赖注入是控制反 ...

  8. Spring IOC&DI 控制反转和依赖注入

    控制反转(Inversion of Control,缩写为IOC),它是把你设计好的对象交给spring控制,而不再需要你去手动 new Object(); 网上对于IOC的解释很多,对程序员而言,大 ...

  9. Spring专题2: DI,IOC 控制反转和依赖注入

    合集目录 Spring专题2: DI,IOC 控制反转和依赖注入 https://docs.spring.io/spring/docs/2.5.x/reference/aop.html https:/ ...

  10. IOC/DI控制反转与依赖注入

    IOC/DI控制反转与依赖注入 IOC和DI表现的效果的是一样的只不过对于作用的对象不同,有了不一样的名字. 先用一个现实的例子来说明IOC/DI表现出来的效果.

随机推荐

  1. 星座物语APP

    效果图: 这里的后台管理用的是duducat,大家可以去百度看说明.图片,文字都在duducat后台服务器上,可以自己修改的.(PS:图片这里是随便找的) http://www.duducat.com ...

  2. 定义Foo() 函数,弹出对话框提示当前选中的是第几个单选框

    function foo(){ var ele = document.getElementsByName("radioElement"); for(var i = 0;i<e ...

  3. Caused by: org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "mil_id")

    今天在使用mybatis处理数据库的时候,突然抛出了上述异常,让我感到很惊讶,因为在处理save的时候,在Mybatis的配置文件中,我根本就没有使用到ognl表达式,系统怎么会抛出上述异常.而且之前 ...

  4. 用命令行批处理bat,设置代理服务器、DNS、网关、WINS等

    http://hi.baidu.com/83050158/blog/item/50cbd63f9da79ccb7d1e711b.html 将下面代码复制到记事本,另存为NetSet.bat,修改相应i ...

  5. 移动端web页面使用position:fixed问题总结

    近期完成了一个新的项目(搜狐直播),其中又涉及到了 fixed(固定位置定位)的问题,在之前的文章<移动Web产品前端开发口诀——“快”>中已经阐述过我对 iScroll 的态度,所以在这 ...

  6. 转载:执行脚本出现bin/bash: bad interpreter: No such file or directory

    转载网址:http://blog.csdn.net/red10057/article/details/8051650 刚刚学习 SHELL 写了一个简单的例子 发生如下错误 -bash: ./test ...

  7. phpcms v9联动菜单实现筛选

    <!--初始化init--> {php $theurl = "index.php?m=content&c=index&a=lists&catid=$cat ...

  8. PHPCMS v9修改栏目或者单页没有权限

    问题: 普通管理员没有权限修改栏目,只有超级管理员才有权限修改,凡是非超级管理员,设置栏目权限后只能添加栏目,不能对栏目进行修改和删除操作,提示您没有权限操作该项这使系统的一个BUG.   一.对于普 ...

  9. HTML5+Css3-webkit-filter

    -webkit-filter 现在规范中支持的效果有: grayscale 灰度 sepia 褐色 saturate 饱和度 hue-rotate 色相旋转 invert 反色 opacity 透明度 ...

  10. JS中typeof与instanceof的区别 (2010-05-26 10:47:40

    JavaScript 中 typeof 和 instanceof 常用来判断一个变量是否为空,或者是什么类型的.但它们之间还是有区别的: typeof typeof 是一个一元运算,放在一个运算数之前 ...