Otra entrega de la serie de patrones de diseño. Hoy el patrón Composite.
Propósito
Componer objetos en estructuras de árbol para representar jerarquías. El patrón permite a los clientes tratar a los objetos individuales y a las composiciones de objetos uniformemente.
Motivación
Las aplicaciones gráficas como los editores para dibujar (Autocad) permiten a los usuarios construir complejos diagramas a partir de componentes simples como lineas y círculos. El usuario puede agrupar componentes para formar componentes mayores (por ejemplo cuatro lineas para formar un cuadrado) y estos a su vez se pueden agrupar para formar componentes aún mayores. Una implementación simple podría definir clases para los objetos simples y otras clases que actuarían como contenedores de esos objetos simples. Sin embargo, hay un problema con esa aproximación. El código que usa esas clases debe tratar los objetos simples y los contenedores de forma diferente, aunque el usuario los trate de forma idéntica la mayor parte del tiempo. El hecho de tener que distinguir estos objetos hace a la aplicación más compleja. El patrón Composite describe cómo usar la composición recursiva para que el cliente no tenga que hacer distinciones.
Ejemplo de uso del patrón Composite
La clave de este patrón es una clase abstracta que representa los objetos simples y su contenedor. Para el ejemplo de las aplicaciones gráficas esa clase es Graphic. Esta clase tiene operaciones como dibujar así como operaciones para acceder y gestionar los hijos. Las clases hijas como Line, Rectangle y Text son los objetos simples y la clase Picture sería el contenedor. La clase Picture define una agregación de objetos Graphic, de forma que los objetos Picture pueden formar otros objetos Picture recursivamente.
Aplicabilidad
El patrón Composite se usa cuando:
- Cuando se quieren representar jerarquías de objetos
- Cuando queremos que los clientes puedan ignorar la diferencia entre composiciones de objetos y objetos individuales.
Estructura
Estructura del patrón Composite
La clase Leaf representa los objetos simples y define su comportamiento. La clase Composite define el comportamiento de componentes que tienen hijos y guarda esos hijos.
Consecuencias
Las ventajas de esta patron son las siguientes:
- Define jerarquías de clases que consisten en objetos simples y en composiciones de esos objetos: Los objetos simples pueden ser compuestos en objetos más complejos que a su vez pueden ser compuestos por otros objetos compuestos y así recursivamente. En cualquier lugar del código del cliente donde se necesite un objeto simple, también se podrá usar un objeto compuesto.
- Hace al cliente más simple: Los clientes pueden tratar los objetos simples y compuestos uniformemente. Los clientes normalmente no saben (y no les debería importar) si están tratando con una hoja (Leaf) o con un objeto Composite. Esto simplifica el código del cliente.
- Hace más fácil añadir nuevos tipos de componentes: Si se define una nueva clase Leaf o Composite, ésta funcionará automáticamente con la estructura que ya estaba definida y el cliente no tendrá que cambiar.
La única pega de este patrón es:
- Puede hacer nuestro diseño demasiado general: La desventaja de hacer más fácil el añadir nuevos componentes es que también hace más difícil restringir los componentes de una composición. A veces queremos que una composición tenga solo un determinado tipo de componentes. Con este patrón tendríamos que hacer las comprobaciones en tiempo de ejecución.
Usos conocidos
Las clases para realizar interfaces gráficas en Java java.awt.Component (Componente), java.awt.Container (Contenedor), java.awt.Panel (Contenedor concreto), java.awt.Button (Botón) entre otras, usan este patrón.
El artículo Patrones de Diseño. Patrón Composite apareció por primera vez en Instinto Binario.