Java Diagramador de Clases Patrón Composite

El patrón Composite sirve para construir objetos complejos a partir de otros más simples y similares entre sí, gracias a la composición recursiva como. Un panal de abejas




Esto simplifica el tratamiento de los objetos creados, ya que al poseer todos ellos una interfaz común, se tratan todos de la misma manera. Dependiendo de la implementación, pueden aplicarse procedimientos al total o una de las partes de la estructura compuesta como si de un nodo final se tratara, aunque dicha parte esté compuesta a su vez de muchas otras. Un claro ejemplo de uso extendido de este patrón se da en los entornos de programación 2D para aplicaciones gráficas. Un videojuego puede contener diferentes capas "layers" de sprites (como una capa de enemigos) pudiéndose invocar un método que actúe sobre toda esta capa de sprites a la vez (por ejemplo, para ocultarlos, darles un filtro de color etc.).


Imaginemos que necesitamos crear una serie de clases para guardar información acerca de una serie de figuras que serán círculos, cuadrados y triángulos. Además necesitamos poder tratar también grupos de imágenes porque nuestro programa permite seleccionar varias de estas figuras a la vez para moverlas por la pantalla.


En principio tenemos las clases Círculo, Cuadrado y Triángulo, que heredarán de una clase padre que podríamos llamar Figura e implementarán todas la operación pintar(). En cuanto a los grupos de Figuras podríamos caer en la tentación de crear una clase particular separada de las anteriores llamada GrupoDeImágenes, también con un método pintar().

Proyecto Diagramador de Clases aplicando el patrón Composite:

Proyecto GitHub Diagramador de Clases en Java



Este es un proyecto desarrollado en el IDE Netbeans Java, usando la librería JGraph, desarrollado en mi etapa de pre grado de la carrera de Ingeniería Informática de la UAGRM. Por lo cual no hay mucha madurez en el desarrollo pero de seguro a más de uno les servirá.

Esta idea de separar en clases privadas componentes (figuras) y contenedores (grupos) tiene el problema de que, para cada uno de las dos clases, el método pintar() tendrá una implementación diferente, aumentando la complejidad del sistema.

Ejemplo genérico aplicando el patrón Composite (fuente wikipedia):

En Java: las clases java.awt.Component (Componente), java.awt.Container (Contenedor), java.awt.Panel (Contenedor concreto), java.awt.Button (Botón)

import java.util.*; public class Client { public static void main(String[] args) { Compuesto raiz = new Compuesto("root"); raiz.agregar(new Hoja("hoja A")); raiz.agregar(new Hoja("hoja B")); Compuesto comp = new Compuesto("compuesto X"); comp.agregar(new Hoja("hoja XA")); comp.agregar(new Hoja("hoja XB")); raiz.agregar(comp); raiz.agregar(new Hoja("hoja C")); Hoja l = new Hoja("hoja D"); raiz.agregar(l); raiz.eliminar(l); raiz.mostrar(1); } } abstract class Componente { protected String nombre; public Componente (String nombre) { this.nombre = nombre; } abstract public void agregar(Componente c); abstract public void eliminar(Componente c); abstract public void mostrar(int profundidad); } class Compuesto extends Componente { private ArrayList<Componente> hijo = new ArrayList<Componente>(); public Compuesto (String name) { super(name); } public void agregar(Componente componente) { hijo.add(componente); } public void eliminar(Componente componente) { hijo.remove(componente); } public void mostrar(int profundidad) { System.out.println(nombre + " nivel: " + profundidad); for (int i = 0; i < hijo.size(); i++) hijo.get(i).mostrar(profundidad + 1); } } class Hoja extends Componente { public Hoja (String nombre) { super(nombre); } public void agregar(Componente c) { System.out.println("no se puede agregar la hoja"); } public void eliminar(Componente c) { System.out.println("no se puede quitar la hoja"); } public void mostrar(int depth) { System.out.println('-' + "" + nombre); } }

Comentarios