Si eres como yo, al desarrollar una aplicación siempre buscas (aunque a veces resulte difícil) utilizar una serie de ‘reglas’ que te ayuden a que el código sea más limpio, esté lo máximo de desacoplado posible, sea escalable…

En un artículo anterior ya hablé sobre los principios SOLID y cómo aplicarlos con Swift. En este artículo voy a tratar sobre un patrón que nos permitirá reducir el acoplamiento de nuestro código y que lo hará más fácilmente testeable: la Inyección de Dependencias.

Pero, ¿qué es la inyección de dependencias?

Si vamos directamente a la definición que nos da Wikipedia, encontramos lo siguiente:

En informática, inyección de dependencias (en inglés Dependency Injection, DI) es un patrón de diseño orientado a objetos, en el que se suministran objetos a una clase en lugar de ser la propia clase la que cree dichos objetos. Esos objetos cumplen contratos que necesitan nuestras clases para poder funcionar (de ahí el concepto de dependencia). Nuestras clases no crean los objetos que necesitan, sino que se los suministra otra clase ‘contenedora’ que inyectará la implementación deseada a nuestro contrato.

Wikipedia

Las ventajas de la inyección de dependencias en Swift son:

  • Reduce el acoplamiento.
  • El código es reusable.
  • El código es testeable.
  • Facilita el mantenimiento del código.

Ejemplo de inyección de dependencias

Por ejemplo, supongamos que estamos preparando una pantalla en la que el usuario puede loguearse en la aplicación, pero para ello necesitamos validarlo en un servidor de internet.

Si estamos utilizando el patrón MVVM y en nuestra clas ViewModel utilizamos una clase que gestione la conexión a internet, incialmente podemos hacer lo siguiente:

Este código funciona correctamente, pero presenta algunos problemas:

  • En primer lugar, es la propia clase LoginViewModel la que crear una instancia de NetworkManager. Esto hace que la dependencia y acoplamiento entre LoginViewModel y NetworkManager sea elevada.
  • Al crear la instancia de NetowrkManager dentro de LoginViewModel, se hace prácticamente imposible testear LoginViewModel de forma independiente (por ejemplo, pasando un mock para la conectividad).

Para solucionar esta situación lo que debemos hacer es modificar el código de la clase LoginViewModel para que le podamos pasar la instancia de NetworkManager:

Testeo de la inyección de dependencias

Ahora, por ejemplo, si queremos testear la clase LoginViewModel podemos pasar una instancia de NetworkManager ‘mockeada’. Es decir, podemos crear nuestra propia clase que tenga el comportamiento que nosotros queramos. Simplemente la nueva clase ha de cumplir el protocolo NetworkManagerProtocol:

O, si queremos testear los errores:

Tipos de inyección de dependencias

Dentro de la inyección de dependencias podemos distinguir tres tipos:

  • Inyección en el inicializador
  • Inyección de propiedades
  • Inyección en métodos

Inyección en el inicializador

Es el tipo de inicialización que hemos visto en el ejemplo. En este caso pasamos la dependencia durante la inicialización del objeto. Además, tiene la ventaja de que la dependencia es inmutable.

Inyección de las propiedades

La inyección de una dependencia también se puede hacer asignándola como parámetro. En este caso esta asignación hace que la propiedad no sea inmutable, ya que luego la podríamos modificar con una nueva asignación:

Inyección en métodos

Otra forma de inyectar una dependencia es hacerlo en el momento que nosotros queramos. Esto se puede hacer creando un método que permita inyectar la dependencia.

Conclusiones

Conocer la inyección de dependencias en Swift nos permitirá crear código más desacoplado, con una menor tendencia a tener errores y cuyo mantenimiento será más sencillo.


0 comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Sígueme en Feedly