java学习之依赖注入、控制翻转

这两天学了反射,首先了解面向对象思想,对一个整体进行分割,体会为‘类’,最终完成的项目由类构成,类是最小的组织单位。类与类如何产生协作?是通过内部通信,即‘调用’来实现的。类与类之间的关系,有组成关系、依赖关系等等。。。类是具体的,接口是抽象的。利用java的语言特性(抽象)----函数是完整有形的,而接口的函数只是一个定义(无形)。

利用接口,我们解决了一半的问题。当两个类产生依赖关系的时候,就会相会影响,但是又不能完全没有关系,完全没有关系是无法进行协作的。因此,就适当的处理它们的关系。类与类之间要相互作用,必须进行通信,而通信就是耦合,耦合产生力的传动。比如在机械学中,两个齿轮,只有咬合在一起,才能传动。也就是说,两个类只有耦合才能协作,那么如果完全没有耦合,就无法协作。所以适当的解耦,才能达到最好的效果。适当的解耦,也叫“松耦合”并不是“零耦合”。

另外一部分是无法通过语言特性来解决问题的,而要通过设计方法来解决。用工厂模式来解决另一半问题,首先解剖问题。

    Test1亲自去new TestImpl(),这就控制权,它决定了自己需要什么对象。反过来,当一个类能决定自己需要的具体对象,就说它具有控制权。现在要剥夺它的控制权,交给第三方(工厂)来做获取具体对象。第三方就是工厂。控制权与依赖是双身关系,有控制权,就有依赖

t2这个对象,被成为依赖件,将获取到的依赖件传入到具体对象中,成为依赖注入。当工厂设计模式完成之后,检查标准是:不论需求如何变更,除了工厂类报错,其它类都不允许报错,那么之后解决工厂类的报错,就一切问题都解决了。

硬编码,出现的具体值,当.java被编译成.class以后,再修改是不可能的,如果要修改,那么之前的class就作废了。那就面临了重新编译。那么,可以改成资源文件-->.java源文件-->.class字节码文件,就可以解决另一半的问题。

Class和.class:

    Class抽象了.class文件。所属的包在哪儿?类名是什么?是否有接口?有没有公开构造函数?有没有其它的函数?等等一系列我们在类文件中看到的,都有相关的抽象。

java语言是具有动态特性的就是能在运行的时候进行加载工作,“运行的时候”运行时(Runtime)在程序运行时加载的就叫动态加载。

Object类型抹除(不包含任何类型信息了或者也可以说类型丢失,向上转型)。

以下展示代码:

package com.zhaohuan.java2;

public class Test {
    private Test2 t2;                //依赖件
    
    public void setT2(Test2 t2) {    //控制权转移出去之后,通过该函数与控制权持有方进行通信,从而获取具体对象
        this.t2 = t2;                //依赖窗口,通过它从外界获取具体依赖件
    }

    public void temp() {
/*        Test2Impl t2 = new Test2Impl();    //因为持有控制权,而产生了耦合,应该控制权(这个思想被称为:控制翻转IoC)
        t2.close();*/
        if(t2 != null) {
            Test2 t = t2;                //消除了所有错误,1、利用接口消除了参考类型的依赖
                                        //2、利用控制反转,消除匿名对象的依赖
            t.close();
        }
    }
}
package com.zhaohuan.java2;

public interface Test2 {
    public void close();
}
package com.zhaohuan.java2;

public class Test3Impl implements Test2 {
    @Override
    public void close() {
        System.out.println("安全关闭");
    }
}
package com.zhaohuan.java2;

import java.util.ResourceBundle;

public class MyFactory {
    private static ResourceBundle rb;
    
    static {
        rb=ResourceBundle.getBundle("my");
    }
    
    /*private static Object getDependency(String className)throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        String dependency=rb.getString(className);
        Class clazz=Class.forName(dependency);
        Object obj=clazz.newInstance();
        return obj;
    }
    
    public static Test2 inverse() throws ClassNotFoundException, InstantiationException, IllegalAccessException  {
        Test3Impl t3=(Test3Impl) getDependency("Test3Impl");
        return t3;
    }*/
    
    public static Object getDependency(String className)throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        String dependency=rb.getString(className);
        Class clazz=Class.forName(dependency);
        Object obj=clazz.newInstance();
        return obj;
    }
    
}
package com.zhaohuan.java2;

import com.zhaohuan.java2.MyFactory;

public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        
        Test2 t2=(Test2) MyFactory.getDependency("Test3Impl");
        Test t = new Test();
        t.setT2(t2);        //fc.inverse()返回了依赖件,然后将依赖件传递给test的对象,
                                    //因为test对象需要用来test2的对象,所以test2是test的依赖件
                                    //那么我们这种将依赖件传递给需要的对象的做法,就叫依赖(件)注入
        t.temp();
    }
}
原文地址:https://www.cnblogs.com/zhaohuan1996/p/8025874.html