📦 El Patrón Composite: Organiza la Jerarquía como un Profesional
El Patrón Composite es uno de los 23 patrones de diseño GangOfFour y resuelve un problema muy común: 
¿Cómo puedes tratar un objeto individual y un grupo de objetos de la misma forma, sin que tu código se vuelva una locura de condiciones if?
La respuesta está en que todos tengan un contrato igual para que todos se comporten de la misma manera.
📦 1. La Analogía “Para Dummies”: La Caja de Mudanza
Imagina que tienes una lista de tareas para una mudanza: calcular el peso total.
- Sin Composite: Tienes que escribir un código para 
CalcularPeso(Libro)y otro código diferente paraCalcularPeso(Caja). Tienes que saber si lo que calculas es una cosa o un grupo de cosas. - Con Composite: Creas un concepto común: “ElementoTransportable”.
 
Elemento (Analogía)  | Rol en Composite  | Comportamiento del Peso  | 
|---|---|---|
| Libro, Taza | Hoja (Leaf)  | Se pesan a sí mismos (son el final de la cadena).  | 
| Caja de Cocina | Compuesto (Composite)  | Le pide el peso a cada “ElementoTransportable” que contiene y luego suma su peso.  | 
Al tratar al Libro y a la Caja como un ElementoTransportable, puedes sumar el peso de la casa entera con una sola llamada, sin importar cuántas cajas anidadas haya.
🌲 2. Los 3 Pilares del Patrón Composite
El patrón de diseño Composite se basa en estos tres roles clave que trabajan juntos:
1. El Componente (El Contrato)
- Es la interfaz o clase abstracta común que define las operaciones que deben implementar todos los elementos.
 - En nuestra ejemplo: Es la etiqueta “ElementoTransportable” que obliga a implementar el método 
calcularPeso(). 
2. La Hoja (El Objeto Básico)
- Representa los objetos finales de la estructura. No tienen “hijos”.
 - En nuestro ejemplo: Un 
Archivoen el sistema de carpetas o unBolígrafoen la caja. - Comportamiento: Simplemente ejecuta la operación sobre sí mismo (ej. devuelve su propio peso).
 
3. El Compuesto (El Contenedor)
- Representa los objetos que pueden contener otros Componentes (Hojas o incluso otros Compuestos).
 - En nuestro ejemplo: Una 
Carpetao unaCaja. - Comportamiento: Implementa la operación delegando la tarea a todos sus hijos y luego combinando sus resultados (ej. itera sobre los elementos de la caja y suma sus pesos).
 
🤔 1. ¿Qué pilar del Patrón Composite representa un objeto que NO puede tener hijos o elementos internos?
📁 3. El Ejemplo Clásico: Sistema de Archivos
El Patrón Composite es la base de cómo funcionan las estructuras de directorios en tu ordenador.
Estructura  | Función (Ej.   | 
|---|---|
| Elemento (Componente) | Define el método   | 
| Archivo (Hoja) | Implementa   | 
| Carpeta (Compuesto) | Implementa   | 
El código que usa esta estructura solo tiene que llamar a CarpetaRaíz.mostrarEstructura() y el patrón se encarga de recorrer el árbol completo, sin saber cuántos niveles de anidación existen.
🤔 2. En el ejemplo de la Carpeta y el Archivo, ¿qué rol cumple el Componente que permite tratar a ambos por igual?
✅ 4. ¿Por Qué Usarlo?
El Composite te da dos beneficios principales:
- Uniformidad: Simplifica el código del cliente, ya que no tiene que distinguir entre elementos simples y complejos.
 - Recursividad Natural: Permite estructuras jerárquicas con profundidad ilimitada, donde las operaciones (como calcular tamaño, mostrar, o buscar) se propagan de forma natural a través de la jerarquía.
 
❌ 5. Desventaja a Considerar
- Demasiada Generalización: A veces, las Hojas no deberían tener el mismo método que el Compuesto (ej. solo el Compuesto tiene el método 
agregarHijo). Al imponer el mismo contrato a ambos, puedes forzar a las Hojas a implementar métodos que no usan (como unArchivo.agregar(otroArchivo)que no tiene sentido). 
🤔 3. ¿Cuál es una desventaja notable del Patrón Composite que mencionamos?
💡 6. Conclusión
El Patrón Composite es esencial para modelar cualquier estructura de datos que se ramifica. Si tu problema implica árboles, listas, o jerarquías (como menús, interfaces gráficas o documentos XML), aplicar el Composite te garantizará un código limpio, extensible y elegante, donde la complejidad se maneja internamente en el objeto Compuesto, y la simplicidad reina en la interfaz.
🧠 7. Ejemplo Práctico en PHP
Vamos a implementar el patrón Composite con la analogía del sistema de archivos (📁 Carpetas y 📄 Archivos).
El objetivo es poder recorrer toda la estructura con una sola llamada a mostrarEstructura().
<?php
// 🔹 1. El Componente (Interfaz común)
interface Elemento {
    public function mostrarEstructura(int $nivel = 0): void;
}
// 🔹 2. La Hoja (Archivo)
class Archivo implements Elemento {
    private string $nombre;
    public function __construct(string $nombre) {
        $this->nombre = $nombre;
    }
    public function mostrarEstructura(int $nivel = 0): void {
        echo str_repeat('  ', $nivel) . "📄 " . $this->nombre . PHP_EOL;
    }
}
// 🔹 3. El Compuesto (Carpeta)
class Carpeta implements Elemento {
    private string $nombre;
    /** @var Elemento[] */
    private array $elementos = [];
    public function __construct(string $nombre) {
        $this->nombre = $nombre;
    }
    public function agregar(Elemento $elemento): void {
        $this->elementos[] = $elemento;
    }
    public function mostrarEstructura(int $nivel = 0): void {
        echo str_repeat('  ', $nivel) . "📁 " . $this->nombre . PHP_EOL;
        foreach ($this->elementos as $elemento) {
            $elemento->mostrarEstructura($nivel + 1);
        }
    }
}
// 🔹 4. Uso del patrón
$documentos = new Carpeta('Documentos');
$imagenes = new Carpeta('Imágenes');
$documentos->agregar(new Archivo('curriculum.pdf'));
$documentos->agregar(new Archivo('contrato.docx'));
$imagenes->agregar(new Archivo('foto1.png'));
$imagenes->agregar(new Archivo('logo.svg'));
$root = new Carpeta('Carpeta Raíz');
$root->agregar($documentos);
$root->agregar($imagenes);
// 🔹 5. Ejecutar la operación común
$root->mostrarEstructura();
🖥️ Salida del programa:
📁 Carpeta Raíz
  📁 Documentos
    📄 curriculum.pdf
    📄 contrato.docx
  📁 Imágenes
    📄 foto1.png
    📄 logo.svg
EA, con esto nos despedimos, saluditos y nos vemos en los bares! 🍻