Ejemplo de inyección de dependencias en PHP

La programación orientada a objetos POO nos invita a diseñar nuestras aplicaciones partiéndolas en partes funcionales más pequeñas, los objetos, que vienen a representar cosas del mundo real.

Los objetos, también llamados instancias, se modelan solamente una vez en las así llamadas clases, que son las que contienen el código de la aplicación. Luego ya puedes crear decenas y cientos de copias a partir de la clase correspondiente, que es como un molde.

Ejemplo de inyección de dependencias en PHP

Las instancias encapsulan conceptos del mundo real (por ejemplo, una persona, un cliente, un automóvil o una transacción electrónica) y, por tanto, tienen unas propiedades y un comportamiento bien definidos. Durante el flujo de ejecución del programa se comunican las unas con las otras como si formaran parte de una orquesta.

Dependencias entre objetos

En cualquier aplicación OOP vamos a tener que enlazar objetos entre sí, o mejor dicho, necesitamos definir dependencias entre objetos. La idea es muy sencilla. Una dependencia no es más que un objeto que necesita una clase para poder funcionar correctamente. ¡Ya está!

Ejemplo: una clase rastreadora de documentos HTML

Imaginemos que estamos desarrollando una aplicación online SEO donde el usuario mete un URL y recibe como resultado un documento PDF con un montón de métricas distintas: número de visitas por mes, errores on-page tales como h1 embebidos en h2, errores de sintaxis, etc.

En una aplicación SEO así necesitamos una clase Crawler, esto es una araña web que va rastreando uno a uno los URLs de un website determinado:

  • https://url-de-ejemplo.tienda/recurso-01
  • https://ejemplo-de-web.tienda/recurso-02
  • https://ejemplo-de-web.tienda/recurso-03
  • https://ejemplo-de-web.tienda/recurso-04

Y almacena los documentos HTML que encuentra en la base de datos, es decir, el cuerpo de las peticiones HTTP exitosas, aquellas que responden con un código de estado 200.

Pues bien, nuestro crawler tiene dos dependencias: un objeto de conexión a la base de datos y un cliente HTTP. ¡Es lo que necesita este componente para poder funcionar!

Nosotros en este ejemplo no utilizaremos curl para obtener los recursos HTTP, ni reinventaremos la rueda, simplemente utilizaremos el cliente Guzzle para hacer las peticiones HTTP.

Código sin inyección vs código con inyección

A continuación adjuntamos dos variantes de la clase Crawler. En la primera instanciamos (hardcodificamos) en Crawler un objeto de tipo \SeoApp\DB y otro de tipo \GuzzleHttp\Client:

De acuerdo a esta variante cuando necesitamos indexar un sitemap, escribimos:

Por otro lado, la variante que inyecta las dependencias es exactamente como la anterior, solo cambia el constructor de la clase, que queda así:

Esta solución es más recomendable, e indexamos el sitemap así:

¿Por qué es mejor inyectar las dependencias?

Las dos clases Crawler de arriba funcionan. Pero el segundo ejemplo es mejor porque el resultado final es más flexible. Las piezas están más desacopladas las unas de las otras, lo que facilita el desarrollo TDD del proyecto, así como el futuro mantenimiento de la aplicación.

Además, la segunda variante nos invita a probar el código con tests unitarios. Es mucho más fácil escribir pruebas PHPUnit cuando hay inyección de dependencias porque nuestras clases son más sencillas y no esconden ningún secreto. Sus dependencias se crean cómodamente fuera de las mismas y podemos crear objetos mock.

Tamién te puede interesar leer esto…

0 comentarios

¿Me dejas un comentario? ¡Gracias!

Deja un comentario

Los campos obligatorios están marcados con *