什么是 Inversion of Control 控制反转

2024-08-26 03:58

本文主要是介绍什么是 Inversion of Control 控制反转,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先解释一下,本篇博客是对博主前两天研究的一篇博客的解释,这里附上这篇博客的链接,大家可以先看一下:
Inversion of Control 控制反转 有什么好处

下面咱们进入正题

定义

首先我们看一下,我们需要关注的几个定义:

依赖倒置原则(Dependency Inversion Principle )

a.高层模块不应该依赖于底层模块,二者都应该依赖于抽象。
b.抽象不应该依赖于细节,细节应该依赖于抽象。

控制反转(Inversion of Control)

在*《精通Spring4.x 企业应用开发实战》*中对IOC的定义是这样的:

IoC(Inversion of Control)控制反转,包含了两个方面:
一、控制。二、反转

*《EXPERT ONE ON ONE J2EE DEVELOPMENT WITHOUT EJB》*第6章:
IoC主要的实现方式有两种:依赖查找,依赖注入。(128页)
依赖注入是一种更可取的方式。(130页)

依赖注入(Dependency Injection)

没有找到明确的定义,下面是wiki上的定义:
In software engineering, dependency injection is a technique whereby one object (or static method) supplies the dependencies of another object. A dependency is an object that can be used (a service).
也可以看下王争的解释:
不通过new() 的方式在类内部创建依赖类对象,而是将依赖的类对象在外部创建好之后,通过构造函数、函数参数等方式传递(或注入)给类使用。

解释

从上面可以看到,IOC离不开DI。
那么到底什么是依赖注入呢,首先我们明确”依赖“在程序中的含义,举个例子,当 class A 用到了 class B中的某些功能时,我们可以说A对B有依赖关系。
在JAVA中,在使用其他类的方法之前,我们首先需要创建该类的对象(在上面的例子中,类A需要创建类B的实例)。
因此,将创建对象的任务转移给其他人/对象 并直接使用依赖项的过程称为依赖注入。

示例

我们通过最上面文章中的例子来看一下依赖注入是为什么引入,并且如何引入进来的,

需求:设计一辆汽车
第一版,实现功能

先设计轮子,然后根据轮子大小设计底盘,接着根据底盘设计车身,最后根据车身设计好整个汽车。
第一版
在这一版,可以看到,Car 依赖 Framework,Framework 依赖 Bottom。。。。而且,Car 的制造依赖 Framework,所以Car 自己造了 Framework,也就是说Car这个对象,需要关心,Framework是如何制造出来的,这样一层一层关心,直到 Tire对象。假如此时我们的Framework的创建发生了变化,Car 就需要也跟着一起变,同理,每一个类的构造函数都直接调用了底层代码的构造函数。假设我们需要改动一下轮胎(Tire)类,把它的尺寸变成动态的,而不是一直都是30。我们需要这样改:
1.5版本
这是Tire大小的改变,假设此时Bottom的大小也要改成动态的,大家可以想象一下,代码又要经历怎样的变动,所以,这显然不是一个很好的设计。

第二版,换一种思路

先设计汽车的大概样子,然后根据汽车的样子来设计车身,根据车身来设计底盘,最后根据底盘来设计轮子。
第二版
在这个设计里,我们运用了依赖注入,通过构造函数传参的方式,那么,为什么通过依赖注入,就可以实现控制反转呢?我们可以看一下,在这个例子里,制造Car需要一个Framework,所以Car就直接在构造函数的参数里接收了一个Framework,Car 不关心这个Framework是谁造的,也不关心这个Framework的创建需要什么东西,Car只是规定了自己需要一个Framework的对象,只要符合这个标准,就可以传进来给Car。

小结

通过上面的例子,我们可以明白,DI是如何实现的,而且通过DI,就可以实现IOC。
那么为什么通过依赖注入的形式,就可以达到控制反转的目的呢?
在这个例子中,我们可以这么理解,一开始,Car需要自己new Framework,此时,Car需要关心Framework是如何创建的,一旦Framework的创建形式有所变化,Car就得跟着变,此时,是上层在依赖下层,第二版时,Car通过参数的形式接收Framework,此时,Car只需要表示,我需要一个Framework,然后等着其他人/对象把Framework提供给它就可以了,Car不会失去对Framework的控制,假设此时,我们把Framework替换为接口,那我们其实就实现了依赖倒置原则DIP:高层模块不应该依赖于底层模块,二者都应该依赖于抽象。这样,这三个定义就统一了起来。

Spring IOC

最后我们再看一下Spring是如何实现IOC的,或者说Spring的IOC,是一个更加完整的IOC。
配置文件
测试代码
可以看到,在这个例子里,Car需要一个Framework,但是,既不是Car来负责Framework的创建,也不是测试代码来负责Framework的创建,而是由第三方容器来负责这个依赖注入的过程,IOC在这里可以解释成,高层不受低层控制,低层也不受高层控制,他们都由第三方来控制。

这篇关于什么是 Inversion of Control 控制反转的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1107480

相关文章

Android实现两台手机屏幕共享和远程控制功能

《Android实现两台手机屏幕共享和远程控制功能》在远程协助、在线教学、技术支持等多种场景下,实时获得另一部移动设备的屏幕画面,并对其进行操作,具有极高的应用价值,本项目旨在实现两台Android手... 目录一、项目概述二、相关知识2.1 MediaProjection API2.2 Socket 网络

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

使用DrissionPage控制360浏览器的完美解决方案

《使用DrissionPage控制360浏览器的完美解决方案》在网页自动化领域,经常遇到需要保持登录状态、保留Cookie等场景,今天要分享的方案可以完美解决这个问题:使用DrissionPage直接... 目录完整代码引言为什么要使用已有用户数据?核心代码实现1. 导入必要模块2. 关键配置(重点!)3.

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

python之流程控制语句match-case详解

《python之流程控制语句match-case详解》:本文主要介绍python之流程控制语句match-case使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录match-case 语法详解与实战一、基础值匹配(类似 switch-case)二、数据结构解构匹

Java反转字符串的五种方法总结

《Java反转字符串的五种方法总结》:本文主要介绍五种在Java中反转字符串的方法,包括使用StringBuilder的reverse()方法、字符数组、自定义StringBuilder方法、直接... 目录前言方法一:使用StringBuilder的reverse()方法方法二:使用字符数组方法三:使用自

Spring Security注解方式权限控制过程

《SpringSecurity注解方式权限控制过程》:本文主要介绍SpringSecurity注解方式权限控制过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、摘要二、实现步骤2.1 在配置类中添加权限注解的支持2.2 创建Controller类2.3 Us

Python中如何控制小数点精度与对齐方式

《Python中如何控制小数点精度与对齐方式》在Python编程中,数据输出格式化是一个常见的需求,尤其是在涉及到小数点精度和对齐方式时,下面小编就来为大家介绍一下如何在Python中实现这些功能吧... 目录一、控制小数点精度1. 使用 round() 函数2. 使用字符串格式化二、控制对齐方式1. 使用

Springboot控制反转与Bean对象的方法

《Springboot控制反转与Bean对象的方法》文章介绍了SpringBoot中的控制反转(IoC)概念,描述了IoC容器如何管理Bean的生命周期和依赖关系,它详细讲解了Bean的注册过程,包括... 目录1 控制反转1.1 什么是控制反转1.2 SpringBoot中的控制反转2 Ioc容器对Bea