Patrón de Diseño Decorador en Java:

El patrón Decorador permite agregar comportamiento adicional a un objeto dinámicamente. Esto se logra mediante la creación de clases decoradoras que implementan la misma interfaz que la clase original y añaden o modifican su funcionalidad. A continuación, te proporciono un ejemplo en Java.

Ejemplo de Decorador en Java:

Supongamos que tienes una interfaz Componente que define un método operacion():

// Interfaz Componente
interface Componente {
    void operacion();
}

Y tienes una implementación concreta de Componente llamada ComponenteConcreto:

// ComponenteConcreto
class ComponenteConcreto implements Componente {
    @Override
    public void operacion() {
        System.out.println("Operación en ComponenteConcreto");
    }
}

Ahora, creamos una interfaz Decorador que también implementa Componente:

// Interfaz Decorador
interface Decorador extends Componente {
    // Puede tener métodos adicionales
    void operacionAdicional();
}

Y creamos una implementación concreta de Decorador llamada DecoradorConcreto:

// DecoradorConcreto
class DecoradorConcreto implements Decorador {
    private Componente componente;

    public DecoradorConcreto(Componente componente) {
        this.componente = componente;
    }

    @Override
    public void operacion() {
        // Decoración adicional antes de la operación original
        System.out.println("Decoración Adicional");
        
        // Llamada a la operación original
        componente.operacion();
        
        // Decoración adicional después de la operación original
        System.out.println("Decoración Adicional");
    }

    @Override
    public void operacionAdicional() {
        System.out.println("Operación Adicional en DecoradorConcreto");
    }
}

Finalmente, puedes usar el DecoradorConcreto para decorar el ComponenteConcreto:

public class Principal {
    public static void main(String[] args) {
        // Crear un ComponenteConcreto
        Componente componente = new ComponenteConcreto();
        
        // Decorar el ComponenteConcreto con el DecoradorConcreto
        Decorador decorador = new DecoradorConcreto(componente);
        
        // Llamar a operaciones
        decorador.operacion();
        decorador.operacionAdicional();
    }
}

Cuándo usar el patrón Decorador:

  1. Añadir Responsabilidades Dinámicamente:
    • Cuando necesitas agregar o quitar responsabilidades a objetos de manera dinámica y flexible.
  2. Evitar la Subclase Proliferation:
    • Para evitar la creación de muchas subclases para manejar todas las combinaciones posibles de características.
  3. Extensiones de Clases Existentes:
    • Cuando deseas extender o modificar el comportamiento de clases existentes sin alterar su código.
  4. Composición en Lugar de Herencia:
    • Para favorecer la composición en lugar de la herencia, permitiendo que las clases sean modificadas y combinadas más fácilmente.

El patrón Decorador es especialmente útil cuando tienes un conjunto de clases con funcionalidades básicas, y deseas agregar características adicionales de manera dinámica sin modificar el código existente. Proporciona una alternativa flexible a la herencia de clases.