Dependecy injection en PHP

starbox

A la hora de programar siempre es deseable buscar la mínima interdependencia entre los módulos o partes del código que encapsulen funcionalidad.

Imaginemos que queremos programar un juego, y que éste podrá publicar en una red social nuestra puntuación.

Veamos el siguiente código:

Hemos escogido publicar nuestra puntuación en Facebook, vemos como para ello el método PublishHighScore() instancia el objeto con su correspondiente configuración.

Si quisiésemos cambiar la red social en la que publicar la puntuación o la configuración para la clase de la red social tendríamos que modificar el código de la clase Game. Este es un caso de interdependencia de código que podemos evitar haciendo uso de una técnica de programación llamada dependency injection (DI a partir de ahora).

Veamos ahora una implementación alternativa:

En este caso la clase Game sólo espera que le suministremos un objeto que implemente el método Publish(), esto hace que podamos modificar las clases que implementen la interfaz SocialNetworkInterface e incluso crear nuevas sin que esto suponga un cambio de código de la clase Game. Vemos que ahora la clase solicita la dependencia mientras antes era la propia clase la que se encargaba de generarla internamente, a esto se le denomina el principio de inversión de control, abreviado, IoC en inglés.

Todo esto es un ejemplo de favorecer la composición frente a herencia en diseño orientado a objectos, y muchas veces es una práctica deseable que nos permite manejar código más flexible e interdependiente de otras partes de la aplicación.

Otra de las ventajas de DI tiene que ver con el diseño de una aplicación orientado a prácticas de testeo, como pueda ser TDD. Podemos diseñar una funcionalidad basada en una “clase A” que dependa de otra “clase B” que aún no esté implementada. Los diversos frameworks de testeo nos permiten crear una clase B ficticia (Mock) con comportamientos predefinidos para cada uno de los métodos asociados a la dependencia. Esto nos permite definir una capa de funcionalidad cuya implementación puede aplazarse en el tiempo sin que esto oculte partes funcionales de la aplicación en desarrollo.

Uno de los patrones asociados a DI más empleados es el denominado Strategy Pattern que implementa un mecanismo que resuelve la siguiente necesidad: variar algoritmos o comportamientos en tiempo de ejecución. Un ejemplo sería el de inyectar a la clase Game un objecto que implemente SocialNetworkInterface mediante el método setSocialNetwork, y que la aplicación contemplase el variar el comportamiento de publicación de puntuación en tiempo de ejecución.

A la forma de introducir dependencias vía constructor normalmente se le llama constructor injection y cuando se hace mediante un setter, setter injection.

Acerca de

Ver todas las entradas de