Siguiendo con los patrones de diseño y su implementación en lenguaje Java, vamos a ver el patrón Composite. Como muchos otros patrones, está presente dentro de la JDK en la estructura de componentes y contenedores de la interfaz gráfica de usuario.
Patrón Composite.
El patrón Composite nos permite construir objetos complejos partiendo de otros más sencillos utilizando una estrategia de composición recursiva. Podemos equiparar este patrón a un panal y sus celdas. Cada objeto simple (celda) puede relacionarse con otros formando una estructura más compleja (panal).
También se puede usar este patrón para tratar a todos los componentes de la estructura en árbol para, mediante una interfaz o superclase, establecer unas reglas de comportamiento que nos permitan tratar a todos los elementos de la misma manera.
Identificaremos los siguientes componentes en la implementación del patrón:
- Interfaz o superclase de comportamiento: En ella estableceremos las pautas de comportamiento que tanto los componentes como el objeto compuesto deberán cumplir.
- Hojas: Serán las clases que implementan la interfaz que define el comportamiento, es decir, cada una de las celdas de nuestro panal.
- Composite: Será la clase que define el objeto compuesto de hojas. En este caso, el panal.
- Cliente: Será la clase que utilice la implementación de este patrón.
Una vez definidas las partes que intervendrán en este patrón, pasamos al ejemplo práctico.
Ejemplo práctico.
Resumen gráfico de la implementación a través de un diagrama UML:
Como podemos observar en la implementación se ha diseñado un sistema de clases que representan distintos productos y pedidos y una interfaz IPrecio.
En la interfaz, definimos el comportamiento como se indicaba con anterioridad, estableciendo un método getImporteTotal() que como aparece en la documentación devuelve el precio del elemento/s.
Cada una de las clases que implementan esta interfaz son hojas del patrón. En este caso hemos distinguido 3 clases:
- ProductoUnitario: representará productos cuya venta se realiza por unidades indivisibles (e.g.: una botella de vino). Estos productos tendrán una serie de características y una forma específica de calcular el precio (precio unitario por número de unidades).
- ProductoPeso: representará productos cuya venta depende del peso del mismo (e.g.: un jamón). Como el anterior, tendrá una serie de propiedades y otra manera distinta de calcular el precio (peso del elemento/s por precio por peso).
- ProductoCompuesto: representará un grupo de productos cuya venta se realiza de forma conjunta (e.g.: una cesta de navidad que contiene varios productos). Esta clase podría desarrollar a la vez los papeles de panal y celda. Contiene una colección de elementos IPrecio que lo conformarán y la implementación del método getImporteTotal() hará llamadas a las implementaciones de cada uno de los elementos de dicha colección.
Como último componente de este patrón vemos la clase Pedido, que es una especialización de la clase ProductoCompuesto que añadirá una serie de propiedades (e.g.: nombre del cliente) y unas funcionalidades añadidas.
Finalmente, crearemos la clase cliente que utilizará esta implementación:
El código fuente de este ejemplo está disponible para descarga aquí.
SEAS es el centro de formación online del Grupo San Valero, especializado en el ámbito técnico, industrial y de empresa. Visita www.seas.es para consultar nuestra oferta formativa de cursos y másteres. Formación profesional para el empleo de calidad y accesible para todos.
marcelo
15 mayo, 2014 at 9:51 pmmuy buen el ejemplo.
saludos