fbpx
Wikipedia

Composite (patrón de diseño)

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 y a una estructura en forma de árbol.

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.).

Es uno de los veintitrés patrones de diseño GoF conocidos que describen cómo resolver problemas recurrentes de diseño para diseñar software orientado a objetos.

Problema que soluciona

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().

Problema.

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.

Implementación

El patrón Composite da una solución elegante a este problema, de la que además resulta en una implementación más sencilla.

A la clase Figura la llamaríamos Gráfico y de ella extenderían tanto Círculo, Cuadrado y Triángulo, como GrupoDeImágenes. Además, esta última tendría una relación todo-parte de multiplicidad * con Gráfico: un GrupoDeImágenes contendría varios Gráficos, ya fuesen éstos Cuadrados, Triángulos, u otras clases GrupoDeImágenes.

Así, es posible definir a un grupo de imágenes recursivamente. Por ejemplo, un objeto cuya clase es GrupoDeImágenes podría contener un Cuadrado, un Triángulo y otro GrupoDeImágenes, este grupo de imágenes podría contener un Círculo y un Cuadrado. Posteriormente, a este último grupo se le podría añadir otro GrupoDeImágenes, generando una estructura de composición recursiva en árbol, por medio de muy poca codificación y un diagrama sencillo y claro.

Diagrama

 

Ejemplos de utilización

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

Código en Kotlin

import java.util.ArrayList abstract class Componente(protected var nombre: String) { abstract fun agregar(c: Componente) abstract fun eliminar(c: Componente) abstract fun mostrar(profundidad: Int) } class Compuesto(name: String) : Componente(name) { private val hijo = ArrayList<Componente>() override fun agregar(componente: Componente) { hijo.add(componente) } override fun eliminar(componente: Componente) { hijo.remove(componente) } override fun mostrar(profundidad: Int) { println("$nombre nivel: $profundidad") for (i in hijo.indices) hijo[i].mostrar(profundidad + 1) } } internal class Hoja(nombre: String) : Componente(nombre) { override fun agregar(c: Componente) { println("no se puede agregar la hoja") } override fun eliminar(c: Componente) { println("no se puede quitar la hoja") } override fun mostrar(depth: Int) { println("-$nombre") } } object Client { @JvmStatic fun main(args: Array<String>) { val raiz = Compuesto("root") raiz.agregar(Hoja("hoja A")) raiz.agregar(Hoja("hoja B")) val comp = Compuesto("compuesto X") comp.agregar(Hoja("hoja XA")) comp.agregar(Hoja("hoja XB")) raiz.agregar(comp) raiz.agregar(Hoja("hoja C")) val l = Hoja("hoja D") raiz.agregar(l) raiz.eliminar(l) raiz.mostrar(1) } } 

Código en C++

#include <iostream> #include <vector> using namespace std; class Component { protected:  string name; public:  Component();  Component(string n);  virtual void add(Component*) {}  virtual void remove(Component*) {}  virtual void show(short) {} }; Component::Component() {} Component::Component(string n) : name(n) {} class Composite : public Component { private:  vector<Component*> list; public:  Composite(string);  void add(Component*);  void remove(Component*);  void show(short); }; Composite::Composite(string n) { name = n; } void Composite::add(Component* component) {  list.push_back(component); } void Composite::remove(Component* component) {  list.erase(std::remove(list.begin(), list.end(), component), list.end()); } void Composite::show(short depth) {  cout << name << " nivel: " << depth << endl;  for(vector<Component*>::const_iterator iter = list.begin(); iter != list.end(); ++iter)  {  if(*iter != 0)  {  (*iter)->show(depth + 1);  }  } } class Leaf : public Component { public:  Leaf (string);  void add(Component*) {}  void remove(Component*) {}  void show(short); }; Leaf::Leaf(string n) { name = n; } void Leaf::show(short depth) {  cout << '-' << name << " (" << depth << ')' << endl; } int main() {  Composite* root = new Composite("raiz");  root->add(new Leaf("hoja A"));  root->add(new Leaf("hoja B"));    Composite* comp = new Composite("rama");  comp->add(new Leaf("hoja A'"));  comp->add(new Leaf("hoja B'"));  root->add(comp);  root->add(new Leaf("hoja C"));  Leaf* h = new Leaf("hoja D");  root->add(h);  root->remove(h);  root->show(1);  delete h;  delete comp;  delete root;  return 0; } 

Código en Java

import java.util.*; public 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); } @Override public void agregar(Componente componente) { hijo.add(componente); } @Override public void eliminar(Componente componente) { hijo.remove(componente); } @Override 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); } } 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); } } 

Código completo en C#

using System; using System.Collections.Generic; namespace WikipediaCompositePattern { public class Program { 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); } } public abstract class Componente { protected string nombre; public Componente (string nombre) { this.nombre = nombre; } public abstract void Agregar(Componente componente); public abstract void Eliminar(Componente componente); public abstract void Mostrar(int profundidad); } public class Compuesto: Componente { private List<Componente> hijo = new List<Componente>(); public Compuesto (string nombre): base(nombre) { } public override void Agregar(Componente componente) { hijo.Add(componente); } public override void Eliminar(Componente componente) { hijo.Remove(componente); } public override void Mostrar(int profundidad) { Console.WriteLine(string.Format("{0} nivel: {1}", nombre, profundidad)); for (int i = 0; i < hijo.Count; i++) hijo[i].Mostrar(profundidad + 1); } } public class Hoja: Componente { public Hoja(string nombre): base(nombre) { } public override void Agregar(Componente componente) { Console.WriteLine("no se puede agregar la hoja"); } public override void Eliminar(Componente componente) { Console.WriteLine("no se puede eliminar la hoja"); } public override void Mostrar(int profundidad) { Console.WriteLine(string.Format("-{0}", nombre)); } } } 
  •   Datos: Q1061379
  •   Multimedia: Composite pattern / Q1061379

composite, patrón, diseño, patrón, composite, sirve, para, construir, objetos, complejos, partir, otros, más, simples, similares, entre, gracias, composición, recursiva, estructura, forma, árbol, esto, simplifica, tratamiento, objetos, creados, poseer, todos, . El patron Composite sirve para construir objetos complejos a partir de otros mas simples y similares entre si gracias a la composicion recursiva y a una estructura en forma de arbol Esto simplifica el tratamiento de los objetos creados ya que al poseer todos ellos una interfaz comun se tratan todos de la misma manera Dependiendo de la implementacion 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 este compuesta a su vez de muchas otras Un claro ejemplo de uso extendido de este patron se da en los entornos de programacion 2D para aplicaciones graficas Un videojuego puede contener diferentes capas layers de sprites como una capa de enemigos pudiendose invocar un metodo que actue sobre toda esta capa de sprites a la vez por ejemplo para ocultarlos darles un filtro de color etc Es uno de los veintitres patrones de diseno GoF conocidos que describen como resolver problemas recurrentes de diseno para disenar software orientado a objetos Indice 1 Problema que soluciona 2 Implementacion 3 Diagrama 4 Ejemplos de utilizacion 5 Codigo en Kotlin 6 Codigo en C 7 Codigo en Java 8 Codigo completo en C Problema que soluciona EditarImaginemos que necesitamos crear una serie de clases para guardar informacion acerca de una serie de figuras que seran circulos cuadrados y triangulos Ademas necesitamos poder tratar tambien grupos de imagenes porque nuestro programa permite seleccionar varias de estas figuras a la vez para moverlas por la pantalla En principio tenemos las clases Circulo Cuadrado y Triangulo que heredaran de una clase padre que podriamos llamar Figura e implementaran todas la operacion pintar En cuanto a los grupos de Figuras podriamos caer en la tentacion de crear una clase particular separada de las anteriores llamada GrupoDeImagenes tambien con un metodo pintar Problema 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 metodo pintar tendra una implementacion diferente aumentando la complejidad del sistema Implementacion EditarEl patron Composite da una solucion elegante a este problema de la que ademas resulta en una implementacion mas sencilla A la clase Figura la llamariamos Grafico y de ella extenderian tanto Circulo Cuadrado y Triangulo como GrupoDeImagenes Ademas esta ultima tendria una relacion todo parte de multiplicidad con Grafico un GrupoDeImagenes contendria varios Graficos ya fuesen estos Cuadrados Triangulos u otras clases GrupoDeImagenes Asi es posible definir a un grupo de imagenes recursivamente Por ejemplo un objeto cuya clase es GrupoDeImagenes podria contener un Cuadrado un Triangulo y otro GrupoDeImagenes este grupo de imagenes podria contener un Circulo y un Cuadrado Posteriormente a este ultimo grupo se le podria anadir otro GrupoDeImagenes generando una estructura de composicion recursiva en arbol por medio de muy poca codificacion y un diagrama sencillo y claro Diagrama Editar Ejemplos de utilizacion EditarEn Java las clases java awt Component Componente java awt Container Contenedor java awt Panel Contenedor concreto java awt Button Boton Codigo en Kotlin Editarimport java util ArrayList abstract class Componente protected var nombre String abstract fun agregar c Componente abstract fun eliminar c Componente abstract fun mostrar profundidad Int class Compuesto name String Componente name private val hijo ArrayList lt Componente gt override fun agregar componente Componente hijo add componente override fun eliminar componente Componente hijo remove componente override fun mostrar profundidad Int println nombre nivel profundidad for i in hijo indices hijo i mostrar profundidad 1 internal class Hoja nombre String Componente nombre override fun agregar c Componente println no se puede agregar la hoja override fun eliminar c Componente println no se puede quitar la hoja override fun mostrar depth Int println nombre object Client JvmStatic fun main args Array lt String gt val raiz Compuesto root raiz agregar Hoja hoja A raiz agregar Hoja hoja B val comp Compuesto compuesto X comp agregar Hoja hoja XA comp agregar Hoja hoja XB raiz agregar comp raiz agregar Hoja hoja C val l Hoja hoja D raiz agregar l raiz eliminar l raiz mostrar 1 Codigo en C Editar include lt iostream gt include lt vector gt using namespace std class Component protected string name public Component Component string n virtual void add Component virtual void remove Component virtual void show short Component Component Component Component string n name n class Composite public Component private vector lt Component gt list public Composite string void add Component void remove Component void show short Composite Composite string n name n void Composite add Component component list push back component void Composite remove Component component list erase std remove list begin list end component list end void Composite show short depth cout lt lt name lt lt nivel lt lt depth lt lt endl for vector lt Component gt const iterator iter list begin iter list end iter if iter 0 iter gt show depth 1 class Leaf public Component public Leaf string void add Component void remove Component void show short Leaf Leaf string n name n void Leaf show short depth cout lt lt lt lt name lt lt lt lt depth lt lt lt lt endl int main Composite root new Composite raiz root gt add new Leaf hoja A root gt add new Leaf hoja B Composite comp new Composite rama comp gt add new Leaf hoja A comp gt add new Leaf hoja B root gt add comp root gt add new Leaf hoja C Leaf h new Leaf hoja D root gt add h root gt remove h root gt show 1 delete h delete comp delete root return 0 Codigo en Java Editarimport java util public 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 lt Componente gt hijo new ArrayList lt Componente gt public Compuesto String name super name Override public void agregar Componente componente hijo add componente Override public void eliminar Componente componente hijo remove componente Override public void mostrar int profundidad System out println nombre nivel profundidad for int i 0 i lt 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 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 Codigo completo en C Editarusing System using System Collections Generic namespace WikipediaCompositePattern public class Program 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 public abstract class Componente protected string nombre public Componente string nombre this nombre nombre public abstract void Agregar Componente componente public abstract void Eliminar Componente componente public abstract void Mostrar int profundidad public class Compuesto Componente private List lt Componente gt hijo new List lt Componente gt public Compuesto string nombre base nombre public override void Agregar Componente componente hijo Add componente public override void Eliminar Componente componente hijo Remove componente public override void Mostrar int profundidad Console WriteLine string Format 0 nivel 1 nombre profundidad for int i 0 i lt hijo Count i hijo i Mostrar profundidad 1 public class Hoja Componente public Hoja string nombre base nombre public override void Agregar Componente componente Console WriteLine no se puede agregar la hoja public override void Eliminar Componente componente Console WriteLine no se puede eliminar la hoja public override void Mostrar int profundidad Console WriteLine string Format 0 nombre Datos Q1061379 Multimedia Composite pattern Q1061379 Obtenido de https es wikipedia org w index php title Composite patron de diseno amp oldid 131890677, wikipedia, wiki, leyendo, leer, libro, biblioteca,

español

, española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos