Serie de práctica de potencia interna de Java: inversión de dependencia, inversión de control e inyección de dependencia

Directorio

1. Explicación de términos

1.1 Principio de inversión de dependencia

1.2 Módulo superior / inferior

1.3 Dependencia

2 Inversión de dependencia

2.1 Antes de confiar en la inversión

2.1 Después de la inversión de dependencia

Inversión de tres controles (IoC)

Inyección de cuatro dependencias (inyección de dependencia)


1. Explicación de términos

1.1 Principio de inversión de dependencia

El principio de inversión de dependencia proviene de seis principios principales de diseño de software, que se definen de la siguiente manera:

  • Los módulos de nivel superior no deberían depender de módulos de nivel inferior, todos deberían basarse en la abstracción.

  • La abstracción no debe depender de los detalles, los detalles deben depender de las abstracciones.

Nota : El módulo de alto nivel es el final de la llamada y el módulo de bajo nivel es la clase de implementación concreta. La abstracción se refiere a interfaces o clases abstractas. Los detalles son la clase de implementación.

En términos simples:  la esencia del principio de inversión de dependencia es hacer que la realización de varios tipos o módulos sea independiente entre sí a través de la abstracción (interfaz o clase abstracta), sin afectarse entre sí y lograr un acoplamiento flexible entre los módulos.

Descripción del problema: la  clase A depende directamente de la clase B. Si desea cambiar la clase A para depender de la clase C, debe lograrlo modificando el código de la clase A. En este escenario, la clase A es generalmente un módulo de alto nivel responsable de la lógica empresarial compleja; la clase B y la clase C son módulos de bajo nivel responsables de las operaciones atómicas básicas; si se modifica la clase A, traerá riesgos innecesarios para el programa.

Solución:  modifique la clase A para que dependa de la interfaz de la interfaz. La clase B y la clase C implementan la interfaz de la interfaz. La clase A se comunica indirectamente con la clase B o la clase C a través de la interfaz de la interfaz, lo que reducirá en gran medida la posibilidad de modificar la clase A.

1.2 Módulo superior / inferior

En una compañía de analogía, la administración es el nivel superior, y el CEO es el nivel superior de todo el grupo empresarial, luego la función de CEO es el nivel inferior. Cada gerente de departamento de arriba es la capa superior, entonces las organizaciones a continuación pueden llamarse la capa inferior. A partir de esto, podemos ver que en un sistema particular, el módulo superior y el módulo inferior se pueden dividir de acuerdo con el nivel de capacidad de toma de decisiones. Luego, al mapear el desarrollo real de nuestro software, generalmente también dividiremos el software en módulos, como la capa empresarial, la capa lógica y la capa de datos.

La capa empresarial es lo que el software realmente quiere hacer , es decir, qué hacer . La capa lógica son los detalles de implementación proporcionados por el software en la etapa actual para las necesidades de la capa empresarial, es decir, cómo hacerlo . La capa de datos se refiere al modelo de datos requerido por la capa empresarial y la capa lógica. Como se resume anteriormente, los módulos se dividen según el nivel de capacidad de toma de decisiones. La capa empresarial está naturalmente en el módulo de la capa superior, y la capa lógica y la capa de datos se clasifican naturalmente como la capa inferior.

1.3 Dependencia

En pocas palabras, la clase A contiene referencias de clase B y la clase A depende de la clase B. En el siguiente ejemplo, Person tiene una referencia a Car y Person depende de Car.

public class Person {

    private Car mCar;

    public Person() {
        mCar = new Car();
    }
}

2 Inversión de dependencia

2.1 Antes de confiar en la inversión

En desarrollos anteriores, escribiríamos código como este:

public class Person {

    private Bike mBike;
    private Car mCar;
    private Plane mPlane;

    public Person(){
        mBike = new Bike();
    }

    public void goToBeijing(){
        System.out.println("以某种交通方式去北京");
        mBike.drive();
    }

    public static void main(String ... args){
        Person person = new Person();
        person.goToBeijing();
    }
}

Creamos una clase de persona. La persona puede elegir cualquier método de transporte para ir a Beijing. Por supuesto, no importa qué método de transporte, conducir un automóvil o volar, cada método de transporte incluye un método goToBeijing () para que la persona llame.

Este es el código básico. En la analogía del código real, el vehículo definitivamente se cambiará con frecuencia. En este momento, los objetos dependientes en la Persona se cambiarán con frecuencia, es decir, el nuevo vehículo (automóvil, avión o bicicleta) en la clase Persona necesita ser cambiado. , Cambios de código, muchos, molestos, alto acoplamiento.

¿Hay alguna forma de resolver el problema anterior? Confíe en el revés!

2.1 Después de la inversión de dependencia

Antes de usar la inversión de dependencia, necesitamos entender la definición de inversión de dependencia:

  • Los módulos de nivel superior no deberían depender de módulos de nivel inferior, todos deberían basarse en la abstracción.
  • La abstracción no debe depender de los detalles, los detalles deben depender de las abstracciones.

La primera es la separación del módulo superior y el módulo inferior. La persona depende del tráfico para emitir el viaje. La persona pertenece al módulo superior, y la bicicleta, el automóvil y el tren pertenecen al módulo inferior. En el código anterior, la persona depende del transporte para viajar.

Analicemos: la persona solo quiere ir a Beijing, y ir a Beijing es abstracto. Cómo ir a Beijing, ya sea volar o conducir un automóvil, este es el detalle. El módulo de nivel superior es Persona. Debe confiar en la abstracción en lugar de los detalles. Mientras se implementen los detalles, es mejor ir a Beijing para tomar el método de transporte específico (es decir, la implementación del método).

public class Person {

    private Bike mBike;
    private Car mCar;
    private Plane mplane;
    private Driveable mDriveable;

    public Person(){
       mDriveable = new Plane();
    }

    public void goToBeijing(){
        System.out.println("以某种交通方式去北京");
        mDriveable.drive();
    }

    public static void main(String ... args){
        Person person = new Person();
        person.goToBeijing();
    }
}

No importa qué método de viaje elija la Persona, para ir a Beijing, simplemente llame al método goToBeijing. Este método llamará automáticamente al método de conducción del vehículo de viaje, ya que en bicicleta o automóvil o avión, estos tres métodos de viaje implementan la interfaz manejable. Esta interfaz es una abstracción. No le importa la implementación específica de su viaje a Beijing, pero no importa qué modo de transporte elija, debe conducir a Beijing.

Se puede ver que la inversión de dependencia es esencialmente una manifestación de la programación orientada a la interfaz.


Inversión de tres controles (IoC)

En el ejemplo anterior, aún necesitamos modificar el código dentro de la clase Persona, y no ha logrado su propósito. Porque la persona aún controla la creación de instancias de su propia clase de implementación concreta mDriveable. Necesitamos mover la instanciación de mDriveable fuera de la Persona, es decir, la Persona entregó la reversión de control de la instanciación de mDriveable interno que él controló, que es la inversión de control, es decir, IoC (Inversión de Control )

public class Person {

    private Driveable mDriveable;

    public Person(Driveable driveable){
        this.mDriveable = driveable;
    }

    public void goToBeijing(){
        System.out.println("以某种交通方式去北京");
        mDriveable.drive();
    }

    public static void main(String ... args){
        Person2 person = new Person2(new Car());
        person.goToBeijing();
    }

}

De esta manera, no importa qué tipo de transporte la Persona elija ir a Beijing, no hay necesidad de cambiar el interior de la clase Persona. La persona transfiere el poder de crear dependencias internas al método main () en la clase. Solo se preocupa por las funciones proporcionadas por la dependencia y no le importa la creación de la dependencia. Ya no crea personalmente objetos manejables. La clase Person se refiere al concepto del contenedor de IoC en IoC .

Esta idea es en realidad IoC. IoC es un nuevo patrón de diseño que desacopla aún más el módulo de capa superior y el módulo de capa inferior. La inversión de control significa invertir el control de dependencia del módulo de capa superior en el módulo de capa inferior.


Inyección de cuatro dependencias (inyección de dependencia)

Lo anterior es la inversión del control, entonces, ¿cómo realizar la inversión del control?

Respuesta:  Inyección de dependencia, DI, Inyección de dependencia. También conocido como DI, es un medio para implementar IoC.

En el ejemplo anterior, entregamos el control de Persona a la instanciación de dependencias, entonces, ¿qué pasa con las dependencias? La persona no puede ser instanciada y dependiente, por lo que debe asignársela externamente (contenedor IoC). Esta acción de asignación tiene un término especial llamado inyección.

Cabe señalar que en el concepto de IoC, este lugar para inyectar dependencias se denomina contenedor de IoC, pero en el concepto de inyección de dependencia, generalmente se denomina inyector.

Para decirlo claramente: no quiero crear instancias de dependencias yo mismo, tú (el inyector) las creas y luego me las inyectas cuando sea apropiado

Hay 3 formas de implementar la inyección de dependencia:

  1. Inyección de constructor

  2. Setter inyección

  3. Inyección de interfaz

/**
 * 接口方式注入
 * 接口的存在,表明了一种依赖配置的能力。
 */
public interface DepedencySetter {
    void set(Driveable driveable);
}
public class Person  implements DepedencySetter {

    //接口方式注入
    @Override
    public void set(Driveable driveable) {
        this.mDriveable = mDriveable;
    }

    private Driveable mDriveable;

    //构造函数注入
    public Person(Driveable driveable){
        this.mDriveable = driveable;
    }

    //setter 方式注入
    public void setDriveable(Driveable mDriveable) {
        this.mDriveable = mDriveable;
    }

    public void goToBeijing(){
        System.out.println("以某种交通方式去北京");
        mDriveable.drive();
    }

    public static void main(String ... args){
        Person2 person = new Person2(new Car());
        person.goToBeijing();
    }
}

 

 

 

 

Artículo de referencia:

Fácil de aprender, análisis de inversión de dependencia (DIP), inversión de control (IOC) e inyección de dependencia (DI): https://blog.csdn.net/briblue/article/details/75093382

 

 

 

174 artículos originales publicados · Me gusta 433 · Visita 320,000+

Supongo que te gusta

Origin blog.csdn.net/LucasXu01/article/details/105462568
Recomendado
Clasificación