IoC究竟shift什么?——IoC的基础分析
IoC全称Inversion of Control,直译为控制反转。这是一种设计理念,并非技术。
在明白控制反转之前,应该知道“反转”反的是什么。
被反转的正转
我们从生活中的做饭场景开始。
在家做菜与餐馆吃饭
我们在做饭的时候有很多个步骤,需要准备原料,厨具等等。最后通过一定的顺序加入我们的原料,再进行翻炒等烹饪操作就能够得到一份菜了。
我们想吃一份菜不一定需要自己做,也可以去餐馆吃,只需要告诉餐馆我们要吃什么,餐馆就能自己做好给到我们手上吃
控制的正与反
在这个做饭的例子中,正转就是我们自己准备原料,自己通过烹饪方法做菜,而控制反转就是我们去的餐馆。
这个时候我相信你还是不明白这俩有什么关系,为什么正转是自己做,而反转变成了餐馆的概念。没关系,我们继续深入。
什么是反转,反转在哪?
我们再回顾一遍,我们吃到菜是个什么流程。
- 自己做饭:想好要做的菜——自己准备原料——自己烹饪——成品
- 餐馆:想好要吃的菜——给餐馆说——餐馆烹饪——成品
我们自己设计一整套程序的时候,往往是有很多模块的,每个模块会相互协作使用,最终形成一个大的程序,我们需要自己一个一个将模块联系起来。这就是我们自己做菜的过程
而控制反转IoC就是将所有需要的模块通过一个容器(可以理解为一个控制终端)联系起来,我们不需要思考这个模块会不会使用其他的模块才能完成,全部都由容器帮我们完成联系。这就是我们去餐馆的过程,我们不用做菜,交给餐馆,而一个个原材料就是餐馆去准备的。
最终我们能看到反转的地方就在于,我们本来是靠自己去一个一个联系其模块来,但我们全都交给了容器,容器替我们完成了联系,我们反转了对自己的依赖,本来是依赖自己去联系的,现在变依赖容器,反转就在这。换句话说,控制反转应该叫控制权反转
为什么要有IoC
这个时候你会说,这样不是省了很多事吗,省事不就是IoC的意义吗?
对了,但没完全对。换句话说,省事了,但没完全省。因为每个依赖还是要我们自己去配置的,只不过换了种方式(这个后面再说),IoC容器只是封装而已,但是这并不代表IoC没用,IoC最大的意义不在于它更方便,而是在于它能解耦。
解耦在哪?
虽然容器只是帮我们完成了每个模块的依赖,但是我们前面说到,控制反转最大的意义就是我们只用把需要的功能给到容器,容器再去思考其他的,这样的话我们再写每个模块功能的时候就会更加独立,不用考虑依赖,每个模块变得更加独立那不就是解耦的初衷吗
实例
我们最后再来个实例看看效果
我们先创建一个接口
public interface Shape {
void draw();
}
然后实现几个个接口
//Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
//Square.java
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
//Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
然后根据传入信息的不同,生成不同的对象
public class ShapeFactory {
//use getShape method to get object of type shape
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
最后main方法调用,获取对象
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
//get an object of Circle and call its draw method.
Shape shape1 = shapeFactory.getShape("CIRCLE");
//call draw method of Circle
shape1.draw();
//get an object of Rectangle and call its draw method.
Shape shape2 = shapeFactory.getShape("RECTANGLE");
//call draw method of Rectangle
shape2.draw();
//get an object of Square and call its draw method.
Shape shape3 = shapeFactory.getShape("SQUARE");
//call draw method of circle
shape3.draw();
}
}
这就是工厂模式,工厂实现的方式原理是根据传入的某个参数获取一个对象,一旦我们新增一个shape类型,就修改ShapeFactory 类。这种方式不够灵活,并违背了软件设计的开闭原则。
开闭原则:一个软件实体, 如类, 模块, 函数等应该对扩展开放, 对修改封闭.
对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对已有代码进行任何修改。
要想做到不修改的动态查看类的类型,反射就是一个不错的选择。
Java 反射(Reflection)是一个强大的特性,它允许程序在运行时查询、访问和修改类、接口、字段和方法的信息。
那么思路就有了,最后的修改就是这样:
public class ShapeFactory {
private ShapeFactory(){}
public static Shape getInstance(String className){
Shape shape = null;
try {
shape = (Shape) Class.forName(className).newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return shape;
}
}
而利用反射的代码就封装到了Class.forName里面
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
IOC底层原理主要用到了3种技术:工厂模式、反射、XML解析
XML文件的配置这里我们不多说,下一章我们具体来说如何做,这里就明白我们的依赖管理都是类似于maven中的pom.xml一样管理的就行。
工厂模式、反射、XML解析的结合完成了IoC的所有技术概括,形成了巧妙的化学反应,我们后面spring都是基于整个概念在前行。
这可能是最好的Spring教程!
感谢您看到这里 这可能是最好的Spring教程系列 更多的文章可以到这查看这可能是最好的Spring教程!即便无基础也能看懂的入门Spring,仍在持续更新。,我还在荔枝更新出最详细的Spring教程
IoC究竟shift什么?——IoC的基础分析的更多相关文章
- 深入理解DIP、IoC、DI以及IoC容器
摘要 面向对象设计(OOD)有助于我们开发出高性能.易扩展以及易复用的程序.其中,OOD有一个重要的思想那就是依赖倒置原则(DIP),并由此引申出IoC.DI以及Ioc容器等概念.通过本文我们将一起学 ...
- 对依赖倒置原则(DIP)及Ioc、DI、Ioc容器的一些理解
1.概述 所谓依赖倒置原则(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体.简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模 ...
- 深入理解DIP、IoC、DI以及IoC容器(转)
深入理解DIP.IoC.DI以及IoC容器 摘要 面向对象设计(OOD)有助于我们开发出高性能.易扩展以及易复用的程序.其中,OOD有一个重要的思想那就是依赖倒置原则(DIP),并由此引申出IoC.D ...
- IoC 之 2.2 IoC 容器基本原理(贰)
2.2.1 IoC容器的概念 IoC容器就是具有依赖注入功能的容器,IoC容器负责实例化.定位.配置应用程序中的对象及建立这些对象间的依赖.应用程序无需直接在代码中new相关的对象,应用程序由IoC ...
- IoC 之 2.1 IoC基础(壹)
2.1.1 IoC是什么 Ioc-Inversion of Control,即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器 ...
- 【转】深入理解DIP、IoC、DI以及IoC容器
原文链接:http://www.cnblogs.com/liuhaorain/p/3747470.html 前言 对于大部分小菜来说,当听到大牛们高谈DIP.IoC.DI以及IoC容器等名词时,有没有 ...
- 再看IOC, 读深入理解DIP、IoC、DI以及IoC容器
IoC则是一种 软件设计模式,它告诉你应该如何做,来解除相互依赖模块的耦合.控制反转(IoC),它为相互依赖的组件提供抽象,将依赖(低层模块)对象的获得交给第三方(系统)来控制,即依赖对象不在被依赖模 ...
- 对依赖倒置原则(DIP)及Ioc、DI、Ioc容器的一些理解(转)
所谓依赖倒置原则(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体.简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合 ...
- 不可不知的DIP、IoC、DI以及IoC容器
面向对象设计(OOD)有助于我们开发出高性能.易扩展以及易复用的程序.当中.OOD有一个重要的思想那就是依赖倒置原则(DIP),并由此引申出IoC.DI以及Ioc容器等概念. 本文首先用实例阐述四个概 ...
- DIP、IoC、DI以及IoC容器
深入理解DIP.IoC.DI以及IoC容器 摘要 面向对象设计(OOD)有助于我们开发出高性能.易扩展以及易复用的程序.其中,OOD有一个重要的思想那就是依赖倒置原则(DIP),并由此引申出IoC.D ...
随机推荐
- SSIS作业提示所请求的 OLE DB 访问接口 Microsoft.ACE.OLEDB.12.0 尚未注册
没有跨不过的坎,也没有解决不了的问题,那些曾经没有把我们打死的困难,最终都会让我们变得更加强大 最近在使用ETL获取Excel数据时,在本地运行没有任何问题,部署到服务器后,使用作业运行时便一直提示以 ...
- DDCA —— 缓存一致性
1. 多处理器内存组织结构 1.1 SMP/集中式共享内存 集中式共享内存多处理器(Centralized shared-memory multiprocessor)或对称共享内存多处理器(Symme ...
- CommonsCollections6(基于ysoserial)
环境准备 JDK1.8(8u421)我以本地的JDK8版本为准.commons-collections(3.x 4.x均可这里使用3.2版本) cc3.2: <dependency> &l ...
- java中的集合包简要分析
1.集合包 集合包是java中最常用的包,它主要包括Collection和Map两类接口的实现. 对于Collection的实现类需要重点掌握以下几点: 1)Collection用什么数据结构实现? ...
- Linux命令之ncdu
简介 Ncdu - NCurses Disk Usage Ncdu 是一个带有 ncurses 接口的磁盘使用分析器. 它旨在在您没有完整图形设置可用的远程服务器上查找空间占用,但即使在常规桌面系统上 ...
- WinUI(WASDK)使用BotSharp框架开发多智能体桌面机器人管理助手(生图开关灯不在话下)
前言 大语言模型(Large Language Models, LLMs)近年来在各行各业中展现出了巨大的潜力和影响力.从自然语言处理到自动化客服,从内容生成到智能助手,LLMs正在改变我们与技术互动 ...
- 十、Spring Boot集成Spring Security之HTTP请求授权
目录 前言 一.HTTP请求授权工作原理 二.HTTP请求授权配置 1.添加用户权限 2.配置ExceptionTranslationFilter自定义异常处理器 3.HTTP请求授权配置 三.测试接 ...
- .NET 中的中间件(Middleware)
ASP.NET Core 中间件 什么是中间件(Middleware)? 中间件是组装到应用程序管道中以处理请求和响应的软件. 每个组件: 选择是否将请求传递给管道中的下一个组件. 可以在调用管道中的 ...
- jsp移动端和pc端页面判断及切换
function goPAGE() { if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobi ...
- Oracle无法远程连接的原因及解决办法
前提 虚拟机Linux(centos7)下静默安装Oracle数据库,本地能访问.文章参考:Linux-CentOS7下安装Oracle11g - sankuoshu - 博客园 (cnblogs.c ...