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:
- Añadir Responsabilidades Dinámicamente:
- Cuando necesitas agregar o quitar responsabilidades a objetos de manera dinámica y flexible.
- Evitar la Subclase Proliferation:
- Para evitar la creación de muchas subclases para manejar todas las combinaciones posibles de características.
- Extensiones de Clases Existentes:
- Cuando deseas extender o modificar el comportamiento de clases existentes sin alterar su código.
- 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.