灵感来源:https://www.cnblogs.com/superjt/p/4311577.html
1. 耦合:
在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑。对象之间耦合度过高的系统,必然会出现牵一发而动全身的情形。
图一
耦合不仅出现在对象与对象之间,也出现在软件系统的各模块之间,以及软件系统和硬件系统之间。如何降低系统之间、模块之间和对象之间的耦合度,是软件工程永远追求的目标之一。为了解决对象之间的耦合度过高的问题,软件专家Michael Mattson提出了IOC理论,用来实现对象之间的“解耦”。
2. 控制反转(IOC):
IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”,还有些书籍翻译成为“控制反向”或者“控制倒置”。
面向对象设计及编程的基本思想大致上就是:把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活地被重用和扩展。
IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦。
图二
IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方”,全部对象的控制权全部上缴给“第三方”IOC容器,IOC容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有人把IOC容器比喻成“粘合剂”的由来。
图三
拿掉IOC容器后的系统,这就是我们要实现整个系统所需要完成的全部内容。这时候A、B、C、D这4个对象之间已经没有了耦合关系,彼此毫无联系,这样的话,当你在实现A的时候,根本无须再去考虑B、C和D了,对象之间的依赖关系已经降低到了最低程度。所以,如果真能实现IOC容器,对于系统开发而言,这将是一件多么美好的事情,参与开发的每一成员只要实现自己的类就可以了,跟别人没有任何关系!(这句话大概是不可能的,毕竟“高内聚,低耦合”,零耦合==零内聚,零内聚的系统大概不能称为“一”个系统了(个人理解))。
(
1、耦合、内聚的评估标准是强度,耦合越弱越好,内聚越强越好;
2、所谓过度指的是由于错误理解导致的效果相反的设计;
3、耦合指的模块之间的关系,最弱的耦合设计是通过一个主控模块来协调n个模块之间的运作。例子:客户要求在界面上增加一个字段,你的项目要修改几个地方呢?如果你只要修改项目文档,那么你的开发构架就是最低强度的耦合,而这种设计 成熟的开发团队都已经做到了,他们使用开发工具通过项目模型驱动数据库和各层次的代码,而不是直接修改那些代码;
4、内聚指的是模块内部的功能,最强的内聚就是功能单一到不能拆分,也就是原子化,
5、所以强内聚和弱耦合是相辅相成的,一个良好的设计是由若干个强内聚模块以弱耦合的方式组装起来的
原文:https://blog.csdn.net/nengyu/article/details/42141635
)
软件系统在没有引入IOC容器之前,如图一所示,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,对象A必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在对象A手上。
软件系统在引入IOC容器之后,这种情形就完全改变了,如图二所示,由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。
通过前后的对比可以看出:对象A获得依赖对象B的过程,由主动行为变为了被动行为。控制权颠倒过来了,这就是“控制反转”这个名称的由来。
3. IOC的别名:依赖注入(DI)
2004年,Martin Fowler探讨了同一个问题,既然IOC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”。他的这个答案,实际上给出了实现IOC的方法:注入。所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。
所以,依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。
4. 理解方式:
以电脑主机和USB外设为例,电脑主机在读取文件的时候,不会关心USB接口上连接的是什么,它的任务就是读取USB接口,连接的外部设备只要符合USB接口标准即可。不论主机USB连接的是U盘还是外置硬盘,控制权在于我,主机无法选择挂载的设备,它只能被动接受(控制反转),电脑主机需要外部设备的时候,根本不用它告诉我,我就会主动帮它挂上它想要的外部设备(依赖注入),在这个过程中,我就起到了IOC容器的作用。
对象A依赖于对象B,当对象 A需要用到对象B的时候,IOC容器就会立即创建一个对象B送给对象A。IOC容器就是一个对象制造工厂,你需要什么,它会给你送去,你直接使用就行了,而再也不用去关心你所用的东西是如何制成的,也不用关心最后是怎么被销毁的,这一切全部由IOC容器包办。
5. 对于工厂模式的理解:
<bean id="appleId" class="com.tsvv.dao.Apple"></bean>
package com.tsvv.dao; interface Fruit{ public void eat(); } class Apple implements Fruit{ @Override public void eat() { System.out.println("——————吃苹果——————"); } } class Orange implements Fruit{ @Override public void eat() { System.out.println("——————吃橘子——————"); } } class Factory{ @SuppressWarnings("unchecked") public static <T> T getInstance(String className){ T t=null; try { t = (T)Class.forName(className).newInstance(); } catch (Exception e) { e.printStackTrace(); } return t; } } public class TestDemo { public static void main(String[] args) { Fruit apple=Factory.getInstance("com.tsvv.dao.Apple"); Fruit orange=Factory.getInstance("com.tsvv.dao.Orange"); apple.eat(); orange.eat(); } }