DIP vs IoC vs DI en el mundo Android

Recientemente me preguntaron en una entrevista: "¿Cuál es la diferencia entre la inyección de dependencia y el principio de inversión de dependencia de SOLID"? Sabía la definición de cada uno de ellos, pero no podía trazar una línea clara entre estos conceptos. En este artículo, quiero describir brevemente la diferencia entre los conceptos del principio de inversión de dependencia (DIP), inversión de control (IoC) e inyección de dependencia (DI) utilizando el ejemplo de una arquitectura pura y un marco de Android. Entonces vamos.



Principio de inversión de dependencia



Definición

R. Los módulos de alto nivel no deben depender de módulos de bajo nivel. Ambos tipos de módulos deben depender de abstracciones.

B. Las abstracciones no deben depender de los detalles. Los detalles deberían depender de la abstracción.


La primera definición incluye el concepto de "módulo". Este es un concepto muy importante sin el cual no se puede entender DIP.



módulo - un conjunto lógicamente interconectado de elementos funcionales



Para evitar malentendidos, considere las definiciones usando un ejemplo. Digamos que necesitamos obtener una lista de libros leídos y mostrársela al usuario. Para ello usaremos las clases BooksInteractor y BooksRepository. Colocamos cada una de estas clases en su módulo BI y BR, respectivamente. El módulo de la clase BooksInteractor depende de la clase BooksRepository.







BooksInteractor'y necesita obtener una lista de libros de BooksRepository. Al Interactor no le importa en absoluto cómo el repositorio recibe estos datos, lo que significa que en este caso BooksInteractor es una abstracción para BooksRepository. Según la segunda definición, BooksInteractor (abstracción) NO debería depender de BooksRepository (implementación). Por otro lado, el repositorio debe conocer el módulo de BI. Entonces, ¿qué sucede: el interactor debe estar dentro del repositorio? No, para invertir las dependencias, solo necesitamos cubrir el BooksRepository con la interfaz IBooksRepository, y poner esta interfaz en el módulo de la clase BooksInteractor. Ahora volvamos a la primera definición de DIP y echemos un vistazo al diagrama.







Mire, los módulos de nivel superior (módulo de BI) no dependen de los módulos de nivel inferior (módulo de BR). Y ambos módulos dependen de la abstracción (en la interfaz de IBooksRepository). Si ha captado la magia de la inversión de dependencias al cubrir un repositorio con una interfaz, comprende el principio de inversión de dependencias. ¡Felicidades! La parte más difícil la entiendes. Puede leer más sobre DIP en este artículo sobre Habré.



Inversión de control



Estudiamos el concepto de "Principio de inversión de dependencia". Pasemos ahora a otra inversión: inversión de control. El concepto en sí es muy amplio y en programación puede significar una de estas tres cosas:



  1. Inversión de interfaces: delegación de la relación entre módulos a una interfaz intermedia. ¿Dónde se aplica? Por ejemplo, en el DIP, que estudiamos antes.
  2. — (, DI/IOC ).
  3. — , . , , — Android . Activity Fragment, .


Dependency Injection



La inyección de dependencias es un mecanismo para pasar sus dependencias a una clase. Siempre te encuentras con esto cuando necesitas pasar una dependencia a otra clase. Hay varias formas de inyectar dependencias: mediante un constructor (Constructor Injection), mediante un método (Method Injection) y mediante una propiedad (Property Injection). Cada uno de estos métodos se utiliza para sus propios fines. Pero aquí es importante entender que Dependency Injection es simplemente pasar una dependencia a un constructor, método o propiedad.



Considerando casos extremos



  • ¿Podría haber DI sin IoC y DIP? Si quizas. Creamos una instancia de una clase A concreta y la pasamos a un objeto de clase B a través de un constructor, método o propiedad.
  • ¿Podría haber DIP sin IoC? No, DIP es una forma de implementar la inversión de interfaz en IoC.
  • ¿Podría haber un DIP sin DI? Sí, podemos vincular los módulos inferiores a la interfaz. Las clases del módulo superior funcionarán con la abstracción de la interfaz, pero la implementación concreta de la clase del módulo inferior se creará en el constructor del módulo superior.


Puede encontrar las diferencias entre DIP, DI e IoC de otros autores aquí y aquí .



¡Me encantaría recibir sus comentarios y sugerencias!



All Articles