个人学习笔记,来自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. Android TagFlowLayout完全解析 一款针对Tag的布局(转)

    一.概述 本文之前,先提一下关于上篇博文的100多万访问量请无视,博文被刷,我也很郁闷,本来想把那个文章放到草稿箱,结果放不进去,还把日期弄更新了,实属无奈. ok,开始今天的博文,今天要说的是Tag ...

  2. 比较好的总结runtime

    http://www.cocoachina.com/ios/20160128/15154.html

  3. Apache调优

    1.调整文件描述符大小,默认Linux系统的文件描述符是1024,对于squid等一些服务来说                在高负载的情况下这些文件描述符是远远不够的,所以在部署该类服务器时修改文件 ...

  4. spring aop切面配置

    <bean id="aopLog" class="sardine.commodity.biz.AopLog"/>    <aop:config ...

  5. lucene实战(第二版)学习笔记

    初识Lucene 构建索引 为应用程序添加搜索功能 Lucene的分析过程

  6. (转)asp.net中Literal与label的区别

    asp.net中Literal与label的区别 一.Literal Web 服务器控件概述(摘于MSDN) 可以使用 Literal Web 服务器控件作为页面上其他内容的容器.Literal 最常 ...

  7. JavaScript 客户端JavaScript之样式表操作(DOM API 提供模块之一)

    层叠样式 表和动态HTML   层叠样式表(CSS)是指定HTML文档或XML文档的表现的标准.     使用CSS和Javascript,可以创建出各种视觉效果,这些效果可以统称为动态HTML(DH ...

  8. 武汉科技大学ACM:1009: 华科版C语言程序设计教程(第二版)习题5.12

    Problem Description 这天老师照例给小豪出了一道题目:老师给小豪一个字符串,让小豪将该字符串逆序输出. Input 第一行包括一个T,表示有多少组测试数据: 接下来T行,每行包括一个 ...

  9. HDU 4605 Magic Ball Game (在线主席树|| 离线 线段树)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意:给出一棵二叉树,每个结点孩子数目为0或者2. ...

  10. CSS定位与浮动

    定位的基本思想很简单,它允许你定义元素框相对于其正常位置应该出现的位置,或者相对于父元素.另一个元素甚至浏览器窗口本身的位置.显然,这个功能非常强大,也很让人吃惊.要知道,用户代理对 CSS2 中定位 ...