Como ya hemos visto en post previos, usar patrones puede hacer nuestro código, más limpio, más eficiente. Hemos visto que al usar los patrones como plantillas predefinidas para nuestras clases, podemos realizar la tarea de desarrollo con más seguridad y en menor tiempo.
En los ejemplos que aquí se presentan se expone la situación para la cual se decidió usar dicho patrón, puesto que los patrones no pueden ser usados en todas las situaciones, mas ben es identificar en nuestro proyecto en donde aplica un patrón. Sobre todo porque es mejor idea usar algo que ya está probado, que empezar desde cero.
Composite
El patrón del que vamos a hablar el día de hoy es útil en situaciones donde debemos tratar grupos de objetos de forma uniforme. El éxito del patrón consiste en crear un medio para que incluso objetos de diferente naturaleza, puedan ser tratados de igual manera. Sobre todo si se trata de arboles jerárquicos, donde un objeto, puede contener otro y este a su vez contener otro. O sea un objeto hijo puede ser un objeto individual o un objeto compuesto. Lo que nos ayuda a preparar nuestro código para adaptarse a futuros cambios en la estructura.
Requerimientos
El proyecto requiere que nuestro sistema sea capaz de agrupar productos para formar paquetes, que deben ser tratados como productos, lo que nos presenta un escenario especial donde un paquete podría contener un producto que a su vez fuera un paquete y así sucesivamente.
Análisis
Entre nuestro proyecto contamos con una clase producto, con sus características y métodos en relación a un producto. El impulso inmediato sería crear una clase grupo para que se encargue de crear estos paquetes; sin embargo, cuando uno de los productos del paquete fuera un Grupo de productos, o sea un paquete; entonces nos meteríamos en problemas, ya que sería necesario modificar nuestro código, si es que no lo consideramos en el análisis.
Manos a la obra
Este ejemplo se implemento sobre la base de las clases que se usaron en el ejemplo del patrón Iterator.
Como en la gran mayoría de los patrones que hemos presentado en el Blog, adivinen que será lo primero que debemos hacer….así es una interface para nuestro Componente que formara parte de nuestro producto, como parte de un conjunto, y una interface para nuestro producto:
La primera clase que debemos crear es la que implementa nuestro componente:
En esta clase implementaremos el patrón Composite. Agregándole un List genérico para almacenar nuestros productos, así como tres métodos:
- Add: El cual nos permite agregar productos a un componente.
- Remove: El cual nos permite eliminar un producto de nuestro componente.
- GetCurrent: Este método nos permite recorrer los productos que forman parte del producto actual. Nótese el uso de Yield, del cual ya hemos hablado en un post previo.
Una vez que hemos codificado nuestro componente, podemos crear nuestra clase producto:
Esta clase hereda de la clase Componente e implementa la Interface IProducto.
Esta clase expone una propiedad donde podemos acceder al precio de nuestro producto, y además un método para obtener el acumulado de los precios de los productos que pudiera contener, esto se realiza usando nuestra interface IConcepto, que definimos en el patrón Iterator, es importante notar que previo a entrar al ciclo asignamos el precio actual de nuestro producto, porque si en vez de acceder a la propiedad Precio se accediera al método GetTotal, debemos regresar nuestro concepto Total con el precio actual. La diferencia es que si accedemos a la propiedad obtendremos un valor float y si accedemos al método obtendremos un objeto que implementa la Interface IConcepto.
Por último nuestro código para probar en la consola:
Observen que usamos la propiedad Precio una vez y en los otros dos, accedimos al método GetTotal, y debido a que este nos devuelve un concepto, pues accedimos a la propiedad Importe del mismo, para obtener el precio.
El cual nos presentara el siguiente resultado:
El poder del código solo es completo, si tenemos el conocimiento de como usarlo
No hay comentarios:
Publicar un comentario