# Patrón Decorator: ampliación dinámica de clases

Si quieres ampliar las funcionalidades de una clase en un *software* orientado a objetos, tienes dos opciones. La opción más fácil es implementar subclases que complementen a la clase base. Sin embargo, esta opción puede volverse confusa. Como alternativa, puedes usar una entidad decoradora según el llamado patrón de diseño Decorador (Decorator Design Pattern). El patrón, que es uno de los 23 Gang of Four (GoF) [Design Patterns](https://www.ionos.com/es-us/digitalguide/paginas-web/desarrollo-web/que-son-los-design-patterns/), permite una expansión dinámica de las clases mientras el *software* está en funcionamiento. Es más, el patrón Decorador funciona sin recurrir a jerarquías de herencia largas y de difícil comprensión.

A continuación, te explicaremos qué es exactamente un patrón de diseño Decorador y cuáles son sus **ventajas y desventajas** y mostraremos su mecánica mediante un gráfico y un ejemplo práctico.

## ¿Qué es un patrón Decorator?

El patrón de diseño Decorador es una estrategia de diseño revelada en 1994 para **expandir la funcionalidad de las clases** dinámicamente en el *software* de computación orientado a objetos. Según este patrón, cualquier objeto puede complementarse con un comportamiento deseado sin influir en las funcionalidades de otros objetos de la misma clase. Desde el punto de vista estructural, el patrón Decorador tiene mucho en común con el patrón Cadena de Responsabilidad (Chain of Responsibility), aunque, en contraste con este, con un procesador central, todas las clases reciben las peticiones.

El componente de *software* que hay que ampliar se “decora” con una o más **clases decoradoras**, que lo envuelven completamente, siguiendo el patrón de diseño Decorador. Cada decorador es del mismo tipo que el **componente al que envuelve** y, por lo tanto, tiene la **misma interfaz**. De esta manera, las llamadas de método entrantes pueden delegarse fácilmente al componente adjunto mientras lleva a cabo una funcionalidad. Las llamadas también pueden procesarse dentro del decorador.

## ¿Cuál es la finalidad del patrón de diseño Decorator?

Al igual que otros patrones GoF, como, por ejemplo, el [patrón Strategy](https://www.ionos.com/es-us/digitalguide/paginas-web/desarrollo-web/strategy-pattern/ "Strategy pattern") o el [Builder](https://www.ionos.com/es-us/digitalguide/paginas-web/desarrollo-web/patron-de-diseno-builder/ "Patrón de diseño Builder"), el patrón Decorator tiene como objetivo hacer que los componentes del *software* orientado a objetos sean más flexibles y fáciles de reutilizar. Con este fin, el enfoque permite a los desarrolladores añadir y **eliminar las dependencias de un objeto de manera dinámica** y, cuando sea necesario, **durante el tiempo de ejecución**. Esto convierte al nombrado patrón en una buena alternativa al uso de subclases, las cuales pueden complementar a una clase, pero no permiten hacer ajustes durante el tiempo de ejecución.

Nota Un componente de *software* puede ampliarse **con un número cualquiera de clases decoradoras**. Estas extensiones son invisibles, lo que significa que normalmente es difícil percibir si una clase real está precedida por clases adicionales.

## El patrón Decorador como diagrama UML

El decorador, o las clases decorador (ConcreteDecorator), tiene la **misma interfaz** que el componente de *software* a decorar (ConcreteComponent) y es del mismo tipo. Estos son requisitos importantes a la hora de **manejar las llamadas**, que pueden remitirse con o sin cambios en función de si el decorador no se encarga de procesarlas. En este concepto, esta interfaz elemental, que es esencialmente una superclase abstracta, recibe el nombre de “componente”.

La interacción entre el componente básico y el decorador es fácilmente visible si **se ilustra** con un [diagrama de clases UML](https://www.ionos.com/es-us/digitalguide/paginas-web/desarrollo-web/diagramas-de-clases-con-uml/ "Diagramas de clases con UML"). Hemos utilizado este lenguaje de modelado para la programación orientada a objetos en el diagrama UML a continuación para entender el patrón Decorator:

[![Imagen: Representación gráfica del patrón Decorator (UML)](https://www.ionos.com/es-us/digitalguide/fileadmin/_processed_/d/0/csm_representacion-grafica-del-patron-decorator_f7f4e1a2af.webp "Representación gráfica del patrón Decorator (UML)")](https://www.ionos.com/es-us/digitalguide/fileadmin/DigitalGuide/Schaubilder/representacion-grafica-del-patron-decorator.png) Representación gráfica del patrón Decorator (UML) ## Pros y contras del patrón de diseño Decorador

Considerar el patrón de diseño Decorator al diseñar un programa es útil por varias razones. En primer lugar, utilizar la estructura Decorador conlleva un **alto grado de flexibilidad**: las funcionalidades de las clases pueden **ampliarse durante la compilación y durante el tiempo de ejecución sin necesidad de recurrir a una jerarquía de clases basadas en la herencia**. Esto mejora significativamente la **legibilidad** del código del programa.

Debido a que la funcionalidad se divide en varias clases decoradoras, el **rendimiento** del *software* puede incrementarse. Esto facilita la recuperación e iniciación de funciones específicas. Con una clase base compleja que proporciona permanentemente todas las funciones, esta **opción de recursos optimizados** no está disponible.

Sin embargo, desarrollar usando el patrón Decorador tiene también algunas desventajas. Con la introducción del patrón **aumenta la complejidad del software** de forma automática. La interfaz Decorador, en particular, suele contener mucho texto y términos nuevos, lo que aumenta su complejidad. Otra desventaja es el **gran número de objetos Decorador**, razón por la cual se recomienda una sistematización separada para evitar **problemas de visualización** al trabajar con subclases. Por último, las largas cadenas de llamadas de los objetos decorados (es decir, los componentes ampliados) **suelen dificultar la detección de errores** y por ende también el proceso de [depuración](https://www.ionos.com/es-us/digitalguide/paginas-web/desarrollo-web/depurador/).

<table>
  <thead>
    <tr>
      <th>Ventajas</th>
      <th>Desventajas</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Alto grado de flexibilidad</td>
      <td>Alta complejidad del software (especialmente la interfaz Decorador)</td>
    </tr>
    <tr>
      <td>Ampliación de las funciones de las clases sin herencia</td>
      <td>De difícil comprensión al principio</td>
    </tr>
    <tr>
      <td>Código de programa legible</td>
      <td>Alto número de objetos</td>
    </tr>
    <tr>
      <td>Funcionalidades optimizadas para los recursos</td>
      <td>Proceso de depuración difícil</td>
    </tr>
  </tbody>
</table>

## Patrón Decorator: ejemplos

El patrón Decorador proporciona la base para implementar **objetos dinámicos, transparentes y expandibles** en un programa. En particular, los componentes de las [**interfaces gráficas de usuario (GUI)**](https://www.ionos.com/es-us/digitalguide/paginas-web/desarrollo-web/que-es-una-gui/) figuran como áreas de aplicación típicas del patrón. Si, por ejemplo, se debe enmarcar un campo de texto, basta con emplazar un decorador “invisible” entre el objeto campo de texto y la llamada para insertar el nuevo elemento de la interfaz.

Un ejemplo muy conocido de la implementación del patrón Decorador lo constituyen las llamadas **clases *stream* de la biblioteca de Java**, respondables de gestionar la entrada y salida de datos. Aquí, las clases Decorador se utilizan para añadir nuevas propiedades e información de estado al flujo de datos o para proporcionar nuevas interfaces.

Java no es el único lenguaje de programación que hace un uso generalizado del patrón Decorador. Los siguientes lenguajes de programación también lo utilizan:

- C++
- C#
- Go
- JavaScript
- Python
- PHP

## Aplicación práctica del patrón Decorator

Como acabamos de ver, el patrón Decorador no es adecuado para todos los tipos de *software*. Sin embargo, cuando **una clase tiene que modificarse *a posteriori***, y especialmente en proyectos en los que esto no se puede conseguir mediante el uso de subclases, el patrón Decorador es una gran solución.

En el ejemplo que presentamos a continuación, el punto de partida es un programa que permite consultar nombres de personas a través de la **clase abstracta “Empleado”**. Sin embargo, la primera letra de los nombres recuperados siempre está en minúsculas. Al ser imposible un ajuste en retrospectiva, se implementa la **clase Decorador *EmpleadoDecorator***, que opera en la misma interfaz y también permite llamar al **método *getName()***. El decorador recibe una lógica que garantiza que la primera letra se escribe correctamente en mayúsculas. En código, esto se escribe así:

```none
public class EmpleadoDecorator implements Person {
private Empleado empleado;
public EmpleadoDecorator(Empleado empleado){
	this.empleado = empleado;
}
public String getName(){
	// llama al método de la clase empleado 
	String name = empleado.getName();
	// Asegúrate de que la primera letra está en mayúsculas
	name = Character.toUpperCase(name.charAt(0)) 
	+ name.substring(1, name.length());
	return name;
}
}
```


This is a markdown version of: [https://www.ionos.com/es-us/digitalguide/paginas-web/desarrollo-web/que-es-el-patron-de-diseno-decorator/](https://www.ionos.com/es-us/digitalguide/paginas-web/desarrollo-web/que-es-el-patron-de-diseno-decorator/) for AI/LLM consumption.