Para utilizar todas las funcionalidades que ofrece este sitio, es necesario tener JavaScript habilitado.

Hablemos acerca de los patrones de diseño! En pocas palabras, los patrones de diseño ofrecen soluciones efectivas y reconocidas a problemas comunes de arquitectura/desarrollo de software. Se hicieron populares através del libro Design Patterns, escrito por un cuarteto de genios conocido como The Gang of Four, por allá en los 90s.

Las ventajas que nos aportan los patrones de diseño son muchas, empezando por que los conceptos pueden adaptarse a cualquier lenguaje de programación y son reutilizables, es decir, los puedes usar para resolver problemas similares en entornos distintos. Adicionalmente nos sirven para estandarizar la comunicación entre otros colegas programadores, dándonos un vocabulario común que podemos usar para discutir soluciones a problemas simples o complejos.

Antes de empezar, me gustaría aclarar un par de cosas. Primero, hay infinidad de patrones de diseño, yo poco a poco, en futuras entradas, iré mostrando los más populares. Segundo, no hay que abusar o forzar el uso de patrones de diseño, estoy convencido que hay que usarlos de forma orgánica y adaptarlos a nuestras necesidades. Por último tampoco se puede pretender que através de los patrones vayamos a solucionar todos nuestros problemas, hay que ser creativos! El reto de usar patrones de diseño radica en reconocer bajo que contextos se pueden aplicar.

Para los ejemplos, voy a usar PHP, empecemos púes!

Inyección de Dependencias

En inglés es conocido como Dependency Injection o DI. Para empezar a hablar de DI, lo primero que debemos hacer, es definir que constituye una dependencia.

Una dependencia es otro objeto necesario para que una clase funcione. Por ejemplo, tenemos una Clase llamada Usuario, que necesita el objeto  Logger para guardar información sobre las acciones del usuario. Bajo esta definición, el objeto Logger es una dependencia de la clase Usuario.

Ahora generalmente para satisfacer una dependencia, lo primero que uno haría, sería algo así:

El problema con este acercamiento es que, al instanciar el objeto dentro de la clase, estamos generando un acoplamiento alto/estrecho (tight coupling), esto hace que nuestro código no sea muy flexible.

A la hora de diseñar o desarrollar software, uno de los principios básicos que, en mi opinión, debemos seguir es: tratar de depender de abstracciones y no de objetos o clases concretas. Precisamente para esto, necesitamos DI.

Que acabamos de hacer?

  • La clase dependiente recibe desde afuera, sus dependencias! Estamos liberando a la clase dependiente, de la construcción de sus dependencias.
  • Al depender solo en abstracciones (en este caso usando usando un interface), podemos sustituir las dependencias, por otros objetos que cumplan el contrato pactado por la interface. Ya empiezas a ver las ventajas?

Como resultado, obtenemos código más flexible, más limpio y más modular. Es común pasar las dependencias al constructor de la clase dependiente, sin embargo también está la opción de usar un método para inyectar dependencias:

Eso es todo! Sencillo cierto? Es un patrón muy fácil de implementar y nos trae muchas ventajas.

Inversión de Control

Llamado Inversion of control o IoC en inglés. Este sería el próximo nivel - después de DI y se usa generalmente cuando el tema de las dependencias se vuelve más complejo.

Como veras, para llamar a la clase A, hay que satisfacer varias dependencias. En estos casos un IoC es algo que nos puede ser útil.

En términos coloquiales, un IoC es simplemente un contenedor con un mapa de dependencias que se necesitan para una clase y la lógica necesaria para crearlas (si es que no han sido creadas aún). Lo que el IoC hace es mirar en su mapa, cuales dependencias se necesitan, ver si ya ha creado instancias de esos objetos y si no es así crearlos, guardarlos para próximos usos y devolver el objeto.

Entonces, en vez de ponerte a construir el objeto que necesitas, le pides al IoC que te devuelva una instancia del objeto que quieras. El IoC, resolverá las dependencias, construirá tu objeto y te lo devolverá. Las ventajas son, que el contenedor puede resolver dependencias complejas de forma transparente y si quieres modificar una dependencia para cambiar el comportamiento, lo único que debes modificar es el contenedor!

En PHP no es muy común el uso de IoCs como en otros lenguajes. Sin embargo, hay uno ligero y reconocido llamado Pimple. Veamos como funcionaría Pimple con el ejemplo anterior:

En Resumen

  • Cuando usar Dependency Injetcion? Casi Siempre!
  • Por Qué? Porque nos ayuda a escribir código que es: fácil de mantener, fácil de extender o modificar, código modular, entendible y limpio.
  • Si estas interesado en practicar Desarrollo guiado por Pruebas (Test Driven Development o TDD en Inglés), DI te va a ahorrar muchos dolores de cabeza.
  • DI nos obliga a planear un poco mejor nuestras dependencias, ayudandonos a decidir si una clase realmente necesita de otro objeto para realizar su función. La idea es pasar exclusivamente los objetos necesarios!

 

Algo que opinar? Cometí algún error? Sácamelo en cara en los comentarios! Si tienes dificultad viendo el código, lo puedes ver directamente en https://gist.github.com/mpratt/5399005.

Bueno, este es el primero de una serie de entradas que pienso escribir acerca de patrones de diseño, espero haya sido útil.

Decidí empezar con DI porque es un patrón muy fácil de entender y además voy a usarlo con frecuencia en los patrones que vaya a abordar en próximas entradas.

Nuevamente, Gracias por leer!

Comentarios