PATRÓN DE DISEÑO “STRATEGY”

Strategy es un patrón de diseño para el desarrollo de software que nos permite definir una familia de algoritmos, encapsula cada uno de ellos y nos permite intercambiarlos. Nos permite que un algoritmo cambie independientemente de los clientes que lo usan.

¿Por qué utilizarlo?

Se nos puede dar el caso de muchas clases relacionadas que únicamente difieren en su comportamiento. Las estrategias nos permiten configurar una clase con un determinado comportamiento entre los muchos comportamientos posibles.

Un algoritmo usa datos que los clientes no deberían conocer. Use el patón Strategy para evitar exponer estructuras de datos complejas y dependientes del algoritmo.

Una clase define muchos comportamientos y estos se representan como múltiples sentencias condicionales en sus operaciones. En vez de tener muchos condicionales, podemos mover las ramas de estos a sus propias clases estrategia.

Strategy_pattern

  • Estrategia (Componedor)

Declara la interfaz común a todos los algoritmos permitidos. El contexto usa esa interfaz para llamar al algoritmo definido por una estrategia.

  • Estrategia Concreta

Implementa el algoritmo concreto.

  • Contexto

Instancia un objeto Estrategia Concreta. Mantiene una referencia a un objeto estrategia (concreta). Puede definir una interfaz que permita a la Estrategia (concreta) acceder a sus datos.

Un ejemplo para entenderlo

Si usted no está familiarizado con los patrones de diseño y buenas prácticas, entonces esta aplicación puede tener un aspecto perfectamente normal para usted. Comprobamos el tipo de método de envío en una enumeración y luego llamamos a un método para calcular el coste en consecuencia.

Strategy_pattern2

¿Qué es erróneo en este código?

Es perfectamente razonable que podamos introducir una nueva compañía en el futuro. Si pasamos una nueva orden de envío al método CalculateShippingCost nos dará una excepción. Tendríamos que extender manualmente la sentencia switch para dar cuenta de la nueva clase de transporte. En caso de una nueva compañía, tendríamos que volver a este servicio de dominio y modificarlo. Esto rompe el principio de abierto / cerrado de SOLID: “una clase está abierta para las extensiones, pero cerrada para modificaciones“. Además, si hay un cambio en la aplicación de uno de los algoritmos de cálculo, de nuevo tendríamos que volver a este método y modificarlo. Esto generalmente no es una buena práctica, si realiza un cambio en una de sus clases, no debería tener que hacer una modificación en otras clases y métodos públicos sólo para dar cabida a ese cambio.

Si un cambio en una parte del proyecto requiere cambios en otra parte del proyecto, entonces lo más probable es que nos enfrentamos a algunos problemas graves de acoplamiento entre dos o más clases.

Además, los métodos que calculan los costes, son por supuesto, ridículamente simples en este ejemplo. En realidad, es muy posible que se hagan llamadas a otros servicios, como el peso del paquete, etc., por lo que la clase ShippingCostCalculatorService puede crecer mucho y sea más difícil mantener. La clase calculadora se ha hinchado con lógica perteneciente a MRW, Seur, etc., violando el principio de responsabilidad individual.

Hay problemas relacionados con el diseño del dominio. Podríamos argumentar que no es responsabilidad del dominio, saber qué método de envío prefiere un cliente.

Solución

La solución es básicamente crear una clase para cada cálculo. Cada clase tendrá que implementar la misma interfaz. Podemos llamar a cada cálculo implementando una estrategia.

La siguiente interfaz cubre nuestras necesidades:

Strategy_pattern3

Lo siguiente es crear las implementaciones de la estrategia:

Strategy_pattern4

El servicio de cálculo de costes ya está listo para aceptar la estrategia desde el exterior:

Strategy_pattern5

Estamos de acuerdo que esta estructura de clases sigue buenos principios de software. Cualquier nuevo cálculo de costes que pueda surgir, se solucionaría implementando el interfaz IShippingStrategy y los demás escenarios no se verán afectados.

Averigue cómo Sogeti puede ayudarle en el Desarrollo Proyectos de TI.

Más información:

JAntonioGonzRomeraJosé Antonio González Romera es Técnico Superior en Desarrollo de aplicaciones informáticas, MCT Sharepoint Developer 2010 y MCPD Asp.Net Framework 3.5. Trabaja como informático desde el año 1999 y se incorporó a Sogeti en Abril de 2006 donde desarrolla aplicaciones para clientes de diversos sectores como sector público, museos, banca o aeronáutica.

Autor: ITblogsogeti

Sogeti es una compañía tecnológica perteneciente al Grupo Capgemini y especialista en: Testing y Calidad de Software; Soluciones Microsoft y High Tech Consulting. En Sogeti entendemos la importancia de obtener el máximo valor empresarial de sus sistemas de IT, por ello somos líderes mundiales en Testing & QA.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s