El Mariachi Orientado a Objetos, Entendiendo el diseño OO

Publicado en

¿Cómo hacen los diseñadores de automóviles para construir un auto compacto, que pueda ser conducido por una persona que mide 1.60 de estatura, y un grandulón de 2.10? La respuesta es sencilla: considerando al momento de diseñar, y antes de fabricar, los potenciales de cambio, tomando así las medidas pertinentes para crear una solución “flexible”: la palanquita que recorre los asientos.

Cuando desarrollamos sistemas, todos nos hemos enfrentado a esta constante de nuestra profesión: el cambio. Cambio de requerimientos, cambio de versiones, cambio de plataforma, etcétera. Para combatirlo, tenemos que dedicar una buena parte del tiempo de análisis y diseño a la flexibilidad de nuestra solución, con el único objetivo de disminuir el riesgo y el costo que éste implica, para tener un cliente satisfecho con menos dinero.

El Mariachi orientado a objetos es un divertido ejemplo de cómo lidiar con los cambios de requerimientos al diseñar clases flexibles, utilizando el patrón de estrategias para diseño orientado a objetos.

Cantemos con Mariachi

Supongamos que tenemos un cliente extranjero cuya pasión musical es desmesurada, y nos ha pedido desarrollar una aplicación que simule la forma de hacer música de un Mariachi, sólo desea integrar un guitarrista, un violinista y un trompetista a la simulación, dado que todos tocan música de diferentes formas y tienen un canto característico, la mayoría comenzaríamos planteando un diagrama de clases similar al mostrado en la figura 1.

Figura 1. Primer acercamiento a la solución.

Nuestro cliente quedó satisfecho con la solución, mas sin embargo, al ver que los integrantes del Mariachi pueden bailar, no esperó mucho para solicitar un cambio de requerimientos: “Ahora quiero Mariachis bailarines”. Nuestro equipo de diseño reacciona rápidamente y agrega el método bailar a la clase Músico. (Véase figura 2).

Figura 2. Mariachi con músicos bailarines.

Al parecer nuestra solución ha sido suficientemente flexible para adaptarse a los cambios, hasta que el cliente nos solicita un nuevo músico: “hagamos una mezcla cultural, quiero escuchar un Mariachi con batería”. Inmediatamente pasa por nuestra mente agregar una nueva clase: Baterista (véase figura 3).

Figura 3. Mariachi con Baterista.

El problema es claro: “Bateristas Bailarines”. Esto lo podemos resolver de una forma muy sencilla, sobrescribiendo el método bailar en Baterista de tal forma que no baile:

public void bailar() {
// hacer nada …
}

Evidentemente, después de este cambio, estamos violando el principio de sustitución de Liskov, el cual indica que “debe ser posible utilizar cualquier objeto instancia de una subclase, en el lugar de cualquier objeto instancia de su superclase sin que la semántica del programa escrito en los términos de la superclase se vea afectado”. En nuestro caso, esto significaría que no será posible reemplazar semánticamente a cualquier Músico por un Baterista, pues el último limita la funcionalidad del primero.

Días mas tarde y aún sin resolver el problema del Baterista, recibimos una nueva petición de nuestro cliente: “¿Cómo podemos agregar un cantante de Ópera a nuestra simulación?”. La figura 4 indica otro “parche” más para satisfacer este requerimiento.

Figura 4. Mariachi con cantante de opera

La solución parece suficiente. No obstante, nos damos cuenta que estamos en un gran aprieto: Cantantes de Ópera que cantan como Mariachi… ¡Ah, y bailan!

Hasta ahora no hemos tenido éxito entre clases rígidas y malos diseños, lo que definitivamente nos convierte en presa fácil de un exceso de presupuesto. Es entonces que uno de los diseñadores sugiere: “intentémoslo con interfaces”.

La figura 5 muestra una solución utilizando interfaces.

Figura 5. Mariachi usando interfaces
Esta solución parece correcta. Incluso hasta el trompetista ha dejado de cantar, para dedicarse únicamente a tocar música y bailar.

Sin embargo, este diseño tiene un problema muy grave: “reutilización de código”. Cuando volteamos y vemos que los métodos bailar, tocar música y cantar tienen que ser implementados por las clases concretas, estamos en aprietos.

Patrón de estrategia

Es en estos momentos, donde el patrón de diseño denominado “Estrategia” llega a nuestro rescate. Este es uno de los patrones descritos en el libro “Gang of Four”, que como sabemos, es la biblia de los patrones de diseño orientado a objetos. De acuerdo con esto, el patrón estrategia: “Define una familia de algoritmos encapsulados y los hace intercambiables (…) permite al algoritmo cambiar, independientemente del cliente que lo utiliza”

En concreto, el patrón de estrategia nos permite construir una colección de comportamientos intercambiables, independientemente de quién haga cantar al Mariachi. La figura 6 muestra la estructura de una solución genérica utilizando el patrón de estrategia.

Figura 6. Solución propuesta por el patrón de estrategia

Lo que tenemos que hacer entonces es encontrar cuáles son los potenciales de cambio, es decir, cuáles clases y/o comportamientos tienen una gran probabilidad de ser modificadas y aislar los cambios de las demás clases, y al mismo tiempo, explotar el polimorfismo agregando una clase abstracta o una interfaz para cubrir las diferentes estrategias.

Siguiendo este consejo, se detecta que el comportamiento de los músicos es el que tiende a cambiar, entonces se decide crear un conjunto de estrategias para cada método con alto potencial de cambio. Para cada una de estas estrategias se construye una interfaz o clase abstracta que define qué es lo que hacen cada uno de los conjuntos de algoritmos, y aplicando el patrón de estrategias obtenemos el resultado en la figura 7.

Figura 7. Mariachi utilizando el patrón de estrategia

 

Bio

Carlos “Fofo” Ordóñez es Ingeniero en Sistemas Computacionales por el ITESO. Actualmente labora como arquitecto de software en Vision Consulting Occidente, ubicada en el Centro de Software de Guadalajara. Colabora como profesor de asignatura en el ITESO, donde imparte materias de Programación e Ingeniería de Software. La información en este artículo representa el punto de vista del autor y no necesariamente el de Vision Consulting o ITESO. fofo@iteso.mx