domingo, 17 de mayo de 2009

COMPOSITE

Nombre

Composite.

Clasificación

Estructural.

Intención

Compone objetos en estructura de árbol y los representa en jerarquías parte todo. Deja a los usuarios manejar objetos simples y compuestos uniformemente.

Motivo

Editores gráficos dejan a los usuarios trabajar con diagramas simples y compuestos. Los usuarios pueden crear grupos compuestos a partir de una lista de componentes, que son agrupados para formar componentes mayores. Una simple implementación sería un grupo de clases que definen gráficas primitivas tales como texto y líneas, y otras clases diferentes actúan como contenedoras de estas primitivas; pero trabajar de esta manera genera un problema; un código que use estas clases debe tratar objetos primitivos y compuestos por separado, aún si la mayoría de veces las trata idénticamente. Esta distinción hace más complejo el sistema, el patrón de diseño composite ofrece una forma de manejar objetos compuestos sin que el usuario tenga que hacer la distinción.

La clave del patrón composite es una clase abstracta, que es la clase padre tanto de objetos simples, como los compuestos. Esta clase incluye métodos para objetos simples y también para los compuestos. Las clases primitivas (simples) no implementaran los métodos de la clase abstracta que actúan sobre los componentes de un objeto (porque son objetos simples); por su lado las clases contenedoras (compuestas), si trabajan todos los métodos. En el patrón los objetos individuales (simples), son las hojas de un árbol, y los compuestos son nodos que contienen las hojas que se derivan de ellos.

Aplicabilidad

Use composite cuando:
• Quiere representar objetos de jerarquías parte todo.
• Quiere que el cliente ignore entre objetos compuestos y objetos individuales, con el objetivo de tratarlos genéricamente.

Estructura



Participantes

• Component: Declara la interfaz para objetos en composición. Implementa comportamiento común para todas las clases. Declara puntos para acceder y manejar las clases leaf.
• Leaf: representa las hojas en un árbol de composición, estas clase s representan objetos individuales.
• Composite: Define el comportamiento para objetos compuetos. Se componen de clases leaf. Implementa los métodos para el manejo y acceso definidos en la clase abstracta component.

Colaboración

El cliente interactúa con component, para utilizar objetos de la estructura de composite, si el objeto es una hoja (leaf), la interacción es directa, si el objeto es un compuesto (composite), éste envía peticiones a sus objetos hijos, posiblemente ejecutando operaciones adicionales, antes o después de la solicitud.

Consecuencias

El patrón composite:
• Define jerarquías de clases consistentes en objetos simples y compuestos. Los objetos simples pueden componer objetos complejos, que pueden componer otros objetos, y así sucesivamente. El cliente puede solicitar objetos simples y compuestos.
• Simplifica el cliente.los clientes pueden tratar objetos compuestos y objetos simples independientemente, el cliente normalmente no sabe si se relaciona con un objeto simple o uno compuesto.
• Facilita la adición de nuevo tipos de componentes.
• Puede hacer el diseño excesivamente general. Lo cual constituye una desventaja debido a que es difícil restringir los componentes de un objeto compuesto.

Implementación

Se deben considerar muchas situaciones cuando se implementa el patrón composite:

• Referencias explícitas a los padres.
• Compartir componentes.
• Maximizar la interface Component.
• Declarar las operaciones de manejo de hijos.
• Implementaría Component una lista de componentes?.
• Orden de los hijos.
• “Caching” para mejorar el rendimiento.
• Quién borraría componentes?.
• Cuál es la mejor estructura de datos para almacenar componentes?.

Código ejemplo

El código ejemplo, es un ejemplo sencillo que muestra como se componen objetos primitivos, para formar compuestos, que a su vez pueden componer a otros. En el ejemplo de la interfaz component heredadn dos compuestos primitivos (componente1, component2) y uno compuesto (composite).

//interfaz component

public interface Component {

public void getName();

public void addComponet(Component c);

public void removeComponent(Component c);

public Component getComponent();

}

//componente primitivo coponente1(leaf)

public class Component1 implements Component {

public Component getComponent() {return null;}

public void getName() {

System.out.println("Componente1");

}

public void addComponet(Component c) {}

public void removeComponent(Component c) {}

}

//Componente primitivo Componenet2 (leaf)

public class Component2 implements Component {

public Component getComponent() {return null;}

public void getName() {

System.out.println("Componente2");

}

public void addComponet(Component c) {}

public void removeComponent(Component c){}

}

//Componente compuesto Composite (Composite)

import java.util.ArrayList;

public class Composite implements Component{

private ArrayList listaComp = new ArrayList();

public Composite(){

}

public Composite(Component c){

this.addComponet(c);

}

public Component getComponent() {

return null;

}

public void getName() {

for (int i=0; i<listaComp.size();i++){

((Component)listaComp.get(i)).getName();

}

}

public void addComponet(Component c) {

listaComp.add(c);

}

public void removeComponent(Component c) {

listaComp.remove(c);

}

}

//Cliente (Client)

public class Cliente {

public static void main(String[] args) {

Component [] c={new Component1(), new Component2()};

Component c2= new Composite();

c2.addComponet(c[0]);

c2.addComponet(c[1]);

Component c3 = new Composite(c2);

c3.addComponet(c[0]);

c3.getName();

c3.addComponet(c[1]);

c3.removeComponent(c2);

System.out.println();

c3.getName();

}

}



Usos conocidos

Ejemplos de composite se encuentran en todos los sistemas orientados a objetos. El visor de clases original de smalltalk fue un composite.

Patrones relacionados

• Chain of resposability se utiliza en combinación con el patrón composite cuando hay que propagar los métodos hacia arriba, en el árbol desde las hojas hasta los nodos.
• Flyweight permite compartir componentes o objetos primitivos en composite.
• Iterator puede ser utilizado para encapsular el recorrido de los coposite (objetos complejos).
• Visitor centraliza operaciones y comportamientos que de otra manera tendrían que ser divididos en las hojas y los composite.

Referencias bibliográficas
[1] Erich Gamma et al, Elements of reusable object-oriented software.
[2] Steve Holzner, Design patterns for dummies, Wiley Publishing Inc, Indianapolis, EEUU, 2006, 339.
[3] Jesús García Molina, Análisis y diseño de software - Patrones de diseño, dis.um.es/~jmolina/astema3