首页 > 其他分享 >IoC究竟shift什么?——IoC的基础分析

IoC究竟shift什么?——IoC的基础分析

时间:2025-01-12 17:43:17浏览次数:1  
标签:draw shift method Shape 反转 IoC public 究竟

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教程

标签:draw,shift,method,Shape,反转,IoC,public,究竟
From: https://www.cnblogs.com/ENchantedN/p/18667122

相关文章

  • Spring-IoC容器
    Spring-IoC容器SpringIoC容器又称为Spring容器,是Spring架构的核心组件,它负责管理应用程序中对象(通常称为bean,bean是IoC容器中的对象实例)的创建、配置、生命周期和依赖关系。IoC容器的基本概念IoC容器又称为容器,是一种设计模式,用于管理应用程序中对象的创建、配置、生命周......
  • 主数据管理与数据虚拟化:究竟哪个先出现?如何协同应用?
    在数据管理的不断发展过程中,有两个关键技术概念脱颖而出,成为企业进行数据驱动决策的基础支柱:主数据管理(MDM)和数据虚拟化。这两种技术虽然常被独立讨论,但它们实际上是高度互补的,携手合作,能够为企业提供一个全面、准确且易于访问的数据视图。那么,问题来了,究竟是主数据管理(MDM)先出......
  • 量化交易的门槛究竟是多少?不同平台量化交易门槛有何差异
    炒股自动化:申请官方API接口,散户也可以python炒股自动化(0),申请券商API接口python炒股自动化(1),量化交易接口区别Python炒股自动化(2):获取股票实时数据和历史数据Python炒股自动化(3):分析取回的实时数据和历史数据Python炒股自动化(4):通过接口向交易所发送订单Python炒股自动化(5):......
  • Agentforce 2.0究竟有什么魔力,Salesforce要做数字领军者?
     2024年12月17日,全球科技巨头Salesforce正式推出其全新平台——Agentforce2.0。首席执行官马克·贝尼奥夫在发布会上宣布,Salesforce计划招聘2000名销售人员,以加速推广这一重大人工智能平台,并预计于2025年2月正式向全球企业提供服务。 Agentforce自今年9月首次亮相以来,便迅......
  • Unity QFrameWork--IOC
    IOCContainerusingSystem;usingSystem.Collections.Generic;namespaceQFramework{publicclassIOCContainer{///<summary>///存储实例///</summary>publicDictionary<Type,object>mInstances=ne......
  • 在计算机操作中,Del(Delete)和 Shift + Del(Shift + Delete)是常见的删除快捷键,它们在文件
    在计算机操作中,Del(Delete)和Shift+Del(Shift+Delete)是常见的删除快捷键,它们在文件或文件夹删除操作上有所不同。下面是Del和Shift+Del的对比,表格形式展示它们的区别:功能/特点Del(Delete)Shift+Del基本作用删除选定的文件或文件夹,但将其移动到回收站(RecycleB......
  • 在 Windows 系统安装过程中,以下是常见的组合键及其功能,表格化整理如下:Ctrl + Shift +
    在Windows系统安装过程中,以下是常见的组合键及其功能,表格化整理如下:快捷键组合功能描述应用场景Ctrl+Shift+F3进入Windows审核模式(AuditMode)用于进入审核模式,可以在安装过程中进行系统自定义设置。F8启动高级启动选项(AdvancedBootOptions)进入安全模......
  • RongIOC---全自动APT威胁情报拓线工具
    公众号:泷羽Sec---风宵对oscp感兴趣的可以私我喔目录公众号:泷羽Sec---风宵RongIOC项目地址:查看帮助文档快速拓线自动拓线获取拓线信息成果展示构建的拓线RongIOC项目地址:https://github.com/WingBy-Fkalis/RongIOC/releases/tag/Bate_v1.0查看帮助文......
  • WebAudioContext.createIIRFilter
    IIRFilterNodeWebAudioContext.createIIRFilter(Array.feedforward,Array.feedback)小程序插件:不支持功能描述创建一个IIRFilterNode参数Array.feedforward一个浮点值数组,指定IIR滤波器传递函数的前馈(分子)系数。Array.feedback一个浮点值数组,指定IIR滤波器传递......
  • WebAudioContext.decodeAudioData
    AudioBufferWebAudioContext.decodeAudioData(ArrayBufferaudioData,functionsuccessCallback,functionerrorCallback)小程序插件:不支持功能描述异步解码一段资源为AudioBuffer。参数ArrayBufferaudioData一个包含音频文件数据的ArrayBufferfunctionsuccessCall......