Wuolah Free 04B. Patron Composite
Wuolah Free 04B. Patron Composite
user_4047924
Programación
Estudios España
Los árboles de objetos se usan mucho por ejemplo en videojuegos para generar
capas y en general en programación gráfica en la que unos objetos contienen a otros
y se enganchan formando un árbol de objetos.
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-8994665
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
El patrón Composite genera un árbol n-ario.
Recuerda las estructuras dinámicas de árbol. Comenzamos con árboles binarios (un
padre y dos hijos) y finalmente vimos un árbol n-ario(1 padre y n hijos). El patrón
composite no es más que una forma ordenada y standard de crear un árbol n-ario de
objetos. Aunque en principio parece que usa complicaciones innecesarias esta
estructura hace que el código sea más fácil de mantener.
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
La principal diferencia entre los árboles que vimos anteriormente y un árbol
composite es que antes teníamos un único tipo de nodo, en composite hay dos tipos
de nodos un tipo es para las hojas(nodos simples ) y el otro para nodos compuestos.
¿Cómo sabíamos trabajando con un único tipo de nodo que un nodo es una hoja?, si
todos sus enlaces a hijos valen null, entonces se trataba de un nodo hoja.
Composite y recursividad.
Observa que la clase Composite tiene una lista de referencias de tipo Componet y
que Composite es un Component, por lo tanto, estamos a un caso de clases que
contienen referencias a si mismo, y como vimos con los nodos de las listas y lo
árboles y en este escenario, la recursividad suele jugar un papel importante para
escribir métodos.
EJEMPLO:
Supongamos que queremos hacer un presupuesto. El presupuesto no es más que el
despiece de una casa con sus precios. Es un ejemplo imaginario no un presupuesto
real.
Casa:
● finca
○ cierre
○ jardín
● estructura
○ tejado
○ alturas
○ sótano
● interior.
○ habitaciones
■ mobiliario
■ pintura
○ electricidad
■ cables
■ operadores
○ fontanería
■ tuberías
■ calefacción
● caldera
● radiadores
Fíjate bien en lo natural que resulta escribir un método getPrecio() recursivo:
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-8994665
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
subpartes de dicha parte. CASO RECURSIVO
quedaría
● Si una parte compuesta no tiene subpartes, es decir, por el momento está
vacía no sumamos nada.. CASO BASE.
● Si una parte es simple (sin subpartes) devolvemos su precio. CASO BASE.
import java.util.ArrayList;
import java.util.List;
@Override
public double getPrecio() {
double precio = 0;
for (ParteAbstracta parte : partes) {
precio += parte.getPrecio();
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-8994665
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
}
@Override
double getPrecio() {
return precio;
}
}
// estructura
ParteSimple tejado = new ParteSimple("tejado", 10000);
ParteSimple alturas = new ParteSimple("alturas", 10000);
ParteSimple sotano = new ParteSimple("sótano", 10000);
ParteCompuesta estructura = new ParteCompuesta("estructura");
estructura.addParte(tejado);
estructura.addParte(alturas);
estructura.addParte(sotano);
// interior
// interior-habitaciones
ParteSimple mobiliario = new ParteSimple("mobiliario", 20000);
ParteSimple pintura = new ParteSimple("pintura", 10000);
ParteCompuesta habitaciones = new ParteCompuesta("habitaciones");
habitaciones.addParte(mobiliario);
habitaciones.addParte(pintura);
// interior-electricidad
ParteSimple cables = new ParteSimple("cables", 500);
ParteSimple operadores = new ParteSimple("operadores", 500);
ParteCompuesta electricidad = new ParteCompuesta("electricidad");
electricidad.addParte(cables);
electricidad.addParte(operadores);
// interior-fontanería
ParteSimple caldera = new ParteSimple("caldera", 4000);
ParteSimple radiadores = new ParteSimple("radiadores", 2000);
ParteCompuesta calefacción = new ParteCompuesta("calefacción");
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-8994665
// todo interior
ParteCompuesta interior = new ParteCompuesta("interior");
interior.addParte(habitaciones);
interior.addParte(electricidad);
interior.addParte(fontaneria);
// la casa completa
ParteCompuesta casa = new ParteCompuesta("Casa");
casa.addParte(finca);
casa.addParte(estructura);
casa.addParte(interior);
}
}
Ejercicio U7_B4B_E1:
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-8994665
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
MENÚS DE CONSOLA Y PATRÓN COMPOSITE
Los típicos menús de consola tienen una estructura arborescente y se les puede
aplicar el patrón composite para ampliar/quitar opciones fácilmente.
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
la clase abstracta se llame -> ComponenteMenu
la clase compuesta se llame ->Menu
la clase simple se llame->MenuItem
Un menú puede contener sub menús pero finalmente llegaremos a los hojas que son
de tipo MenuItem
Menú archivo
-------------------
0. Nuevo archivo
1. Abrir archivo
2. Guardar archivo
3. Salir
Teclea número opcion: 0
ejecutando cosas de Nuevo archivo
pulsa tecla para regresar a menú anterior
-------------------------------
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-8994665
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Menú mi editor
-------------------
0. archivo
1. Editar
2. Salir
Teclea número opcion: 2
Chao
Observa que tras ejecutarse un menuItem o un menú tenemos que volver al menú
padré que lo invocó. Nos hará falta entonces tener un atributo Padre en los
Componentes para almacenar la referencia al objeto Padre que nos permite “subir”
por el árbol
Utiliza la siguiente clase abstracta para resolver el ejercicio:
abstract class ComponenteMenu {
protected ComponenteMenu padre;
protected String nombre;
Scanner sc;
Tu solución debe funcionar al menos para los tests del siguiente main() que lanza una salida
como la del ejemplo de salida de arriba.
public class App {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-8994665
MiMenu.ejecutar();
}
}
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
En el siguiente ejemplo se puede intuir que la librería gráfica swing del JDK utiliza el
patrón Composite internamente para dar soporte a la confección de menús.
Lógicamente hay muchas cosas que no entenderás en el ejemplo, fíjate simplemente
como se usan objetos JMenu(objeto compuesto) y JMenuItem(hoja) y como hay
métodos add para añadir a los arrayList internos de los objetos JMenu
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
menuOperaciones.add(itemSumar);
menuOperaciones.add(itemRestar);
menuSalir.add(itemSalir);
mb.add(menuOperaciones);
mb.add(menuSalir);
itemSumar.addActionListener(lSumar);
itemRestar.addActionListener(lRestar);
itemSalir.addActionListener(lSalir);
setJMenuBar(mb);
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-8994665
setLayout(new FlowLayout());
setVisible(true);
}
}
public class App{
public static void main(String[] args) {
new MiFrame();
}
}
a64b0469ff35958ef4ab887a898bd50bdfbbe91a-8994665
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.