Composite (padrón de deseño)

**Composite** é un padrón de deseño que integra obxectos en estruturas en árbore para representar xerarquías de parte-todo. É un padrón de tipo estrutural xa que nos indica como almacenar os obxectos en memoria, neste caso en estrutura de árbore. Permite aos clientes tratar os obxectos individuais e aos compostos de forma uniforme.

## Propósito 
O seu propósito é construír obxectos formados por outros máis simples, pero semellantes entre si, por medio da composición recursiva, simplificando o seu tratamento ao ter todos unha interface común que ignora as diferenzas entre obxectos individuais e compostos. Resolve o problema de representar xerarquías de obxectos de tipo parte-todo.

## Estrutura 
miniatura|centro|400px|Diagrama da estrutura do padrón Composite.

## Participantes 
* **Compoñente**: declara a interface para os obxectos na composición, mediante a cal se permite o acceso e modificación dos fillos. 
* **Folla**: representa os obxectos da composición que non teñen fillos e introduce as súas operacións.
* **Composto**: pon en funcionamento as operación para os elementos compostos con fillos e almacena os mesmos (os fillos poden ser follas ou compostos). A súa operación (ou operacións) normalmente redirixe a petición aos fillos e realiza algunha acción adicional.
* **Cliente**: utiliza os obxectos da composición mediante a interface compoñente.

## Consecuencias 
As principais consecuencias de aplicar este padrón son a simplificación para o cliente na forma de tratar os obxectos, xa que os usará dunha forma uniforme, e a facilidade de agregar novos tipos de compostos sen afectar ao cliente.

Unha desvantaxe deste modelo é a dificultade á hora de restrinxir compoñentes dunha composición, sendo necesario, normalmente, engadir comprobacións en tempo de execución.

No caso de maximizar a interface compoñente engadíndolle operacións necesarias para os compoñentes pódese entrar en conflito có principio de deseño da xerarquía de clases, xa que teríamos operacións non significativas para as subclases, e presenta problemas de seguridade ao permitir aos clientes realizar operacións pouco significativas para as follas.

## Aplicabilidade 
O padrón composite pode empregarse cando o cliente deba ignorar as diferenzas entre os obxectos individuais e os compostos. Por exemplo, é amplamente usado no tratamento de interfaces de usuario nas que se precisa representar un conxunto de elementos da interface gráfica. Algúns destes elementos serán simples, e outros estarán formados por varios elementos simples (os compostos), de forma que o seu comportamento estará determinado polos elementos que o compoñen.

## Variantes 
miniatura|centro|500px|Variante na que os fillos coñecen ao pai.

* Pódense almacenar referencias explícitas ao pai, se fose necesario percorrer a árbore en sentido inverso. Para levar a cabo esta modificación necesitariamos engadir en Compoñente as operacións obterPai i establecerPai, as cales deberían de ter visibilidade protexida, xa que son necesarias para uso interno da composición e o usuario non debería poder empregalas. Ademais modificariamos a operación engadir, dende a cal se chamaría a establecerPai.
* Pódense almacenar os fillos ordenados, optimizando así a súa obtención.
* Ao traballar con obxectos moi pesados pode interesar compartilos, producíndose un cambio na estrutura, xa que a árbore pasa a ser un grafo dirixido acíclico.

miniatura|centro|300px|Exemplo de compartición de fillos.

* Lista de compoñentes en composto: simplifícase o modelo eliminando a clase composto. Isto fai que os fillos precisen de máis espazo, pero pode merecer a pena se hai poucos nodos folla.
* Mellora do rendemento mediante o uso de cachés en composto, de forma que cada obxecto composto garde información sobre os seus fillos. Emprégase se queremos obter con frecuencia algunha información concreta dos fillos , pero penaliza a operación de actualización ( exemplo de diagrama no que cada composto sabe o número de fillos que ten).

miniatura|centro|500px|Exemplo do uso de cachés.

* Responsabilidade de borrado: xeralmente o responsable de borrar aos fillos será o pai, de forma que se o queremos eliminar encargarase da eliminación dos fillos.
* A estrutura de datos para almacenar aos fillos non se deberá decidir na etapa de deseño, senón na de posta en funcionamento, dependendo da estrutura de datos máis eficiente para cada caso concreto.

## Exemplo 
miniatura|centro|500px|Exemplo de aplicación do padrón Composite.

## Véxase tamén 
### Bibliografía 
* E. Gamma, R. Helm, R. Johnson, J. Vlissides: *Design Patterns. Elements of Reusable Object-Oriented Software*. Addison-Wesley Professional Computing Series.