En este artículo vamos a adentrarnos en el mundo de los patrones de diseño. Comenzando con los patrones de comportamiento y, en particular, con el patrón STRATEGY. Allá vamos!
Como comenté en el artículo introductorio a los patrones de diseño (acá el link), un patrón de comportamiento es aquel que gestiona algoritmos, relaciones y responsabilidades entre objetos.
También vimos que hay 4 elementos que definen un patrón. Así que vamos a utilizarlos para exponer el patrón STRATEGY.
Patrón STRATEGY
Nombre: STRATEGY
Problema: Cambios de comportamiento en tiempo de ejecución.
Solución: Tener una clase (la cual depende de nuestro contexto) que tenga un atributo que sea del tipo de una interfaz que le indicará al contexto que estrategia utilizar. Va a haber 'X' implementaciones de la interfaz, siendo 'X' la cantidad de estrategias distintas a realizar. Al momento de crear la clase contexto se le indica que estrategia va a utilizar y al querer cambiarla en tiempo de ejecución, simplemente se le provee una nueva estrategia para utilizar.
Consecuencias:
- Ventajas: Permite cambiar el comportamiento de la clase de manera dinámica sin poner condiciones dentro de la clase contexto. Permite encapsular comportamiento para reutilizarlo y no repetir código. Permite modificar comportamiento sin tener que modificar las clases de contexto.
- Desventajas: La aplicación debe estar al tanto de todas las posibles estrategias para seleccionar la adecuada para cada situación. Todas las estrategias deben implementar la misma interfaz, esto hace que algunas estrategias tengan que implementar métodos que no necesitan para su comportamiento.
Ejemplo:
Ahora vamos a ver un ejemplo práctico para dejar las cosas en claro. Para ello vamos a utilizar un juego conocido por todos, algunos mas que otros pero la mayoría se saben las reglas básicas, el ajedrez.
El siguiente diagrama muestra la solución que primero sale pensando en objetos:
En el se ve una clase pieza de la cual heredan todas las distintas piezas (peón, torre, caballo, alfil, reina y rey). Cada una de ellas implementa el método abstracto mover de Pieza.
Esto nos obliga a que, en el caso de que una de las piezas deba cambiar la manera en la cual se mueve, tengamos que eliminar dicha pieza y crear una nueva con el movimiento deseado.
Si ahora aplicamos el patrón STRATEGY, el diagrama queda de la siguiente manera:
En el se ve una clase pieza que tiene un atributo de tipo Movimiento que es una interfaz. Dicha interfaz está siendo implementada todos los diferentes comportamientos que nosotros queramos (en este caso serían los diferentes movimientos). La clase Pieza utiliza el movimiento seteado para decidir como se va a mover. En caso de que un peón corone (llegue al extremo del tablero del contrincante) este se puede convertir en un caballo, un alfil, una torre o una dama. Esto hace que tengamos que cambiar el comportamiento de la pieza por un movimiento distinto. Eso con el patrón STRATEGY es muy simple, sólo hay que setearle un nuevo movimiento a la pieza y listo, se mueve como otra!
Con eso concluyo este capítulo, mostrando lo importante que es ver como es el comportamiento requerido para armar nuestras clases y relaciones. Si está bien planteado esto, la solución termina siendo sencilla.
Por esto es que no hay que usar patrones porque sí, hay que usarlos cuando solucionan nuestra problemática.
Próximamente estaré subiendo otro artículo pero de patrones estructurales.
Hasta luego!