---
title: Decorator
category: Structural
language: es
tag:
  - Gang of Four
  - Extensibility
---

## También conocido como

Wrapper

## Propósito

Adjunte responsabilidades adicionales a un objeto de forma dinámica. Los decoradores proporcionan una alternativa
flexible a la subclase para ampliar la funcionalidad.

## Explicación

Ejemplo real

> En las colinas cercanas vive un trol furioso. Normalmente va con las manos desnudas, pero a veces lleva un arma. Para
> armar al troll no es necesario crear un nuevo troll sino decorarlo dinámicamente con un arma adecuada.

En pocas palabras

> El patrón decorador permite cambiar dinámicamente el comportamiento de un objeto en tiempo de ejecución envolviéndolo
> en un objeto de una clase decoradora.

Wikipedia says

> En programación orientada a objetos, el patrón decorador es un patrón de diseño que permite añadir comportamiento a un
> objeto individual, ya sea de forma estática o dinámica, sin afectar al comportamiento de otros objetos de la misma
> clase. El patrón decorador suele ser útil para adherirse al Principio de Responsabilidad Única, ya que permite dividir
> la funcionalidad entre clases con áreas de interés únicas, así como al Principio Abierto-Cerrado, al permitir extender
> la funcionalidad de una clase sin modificarla.

**Ejemplo programático**

Tomemos el ejemplo del troll. En primer lugar tenemos un `SimpleTroll` que implementa la interfaz `Troll`:

```java
public interface Troll {
  void atacar();
  int getPoderAtaque();
  void huirBatalla();
}

@Slf4j
public class SimpleTroll implements Troll {

  @Override
  public void atacar() {
    LOGGER.info("¡El troll intenta atraparte!");
  }

  @Override
  public int getPoderAtaque() {
    return 10;
  }

  @Override
  public void huirBatalla() {
    LOGGER.info("¡El troll chilla de horror y huye!");
  }
}
```

A continuación, queremos añadir un palo para el troll. Podemos hacerlo de forma dinámica mediante el uso de un
decorador:

```java
@Slf4j
public class TrollConGarrote implements Troll {

  private final Troll decorado;

  public TrollConGarrote(Troll decorado) {
    this.decorado = decorado;
  }

  @Override
  public void atacar() {
    decorado.atacar();
    LOGGER.info("¡El troll te golpea con un garrote!");
  }

  @Override
  public int getPoderAtaque() {
    return decorado.getPoderAtaque() + 10;
  }

  @Override
  public void huirBatalla() {
    decorado.huirBatalla();
  }
}
```

Aquí está el troll en acción:

```java
// troll simple
LOGGER.info("Un troll de aspecto simple se acerca.");
var troll = new SimpleTroll();
troll.atacar();
troll.huirBatalla();
LOGGER.info("Poder del troll simple: {}.\n", troll.getPoderAtaque());

// cambia el comportamiento del troll simple agregando un decorador
LOGGER.info("Un troll con un enorme garrote te sorprende.");
var trollConGarrote = new TrollConGarrote(troll);
trollConGarrote.atacar();
trollConGarrote.huirBatalla();
LOGGER.info("Poder del troll con garrote: {}.\n", trollConGarrote.getPoderAtaque());
```

Salida del programa:

```java
Un troll de aspecto simple se acerca. 
¡El troll intenta atraparte!
¡El troll chilla de horror y huye!
Poder del troll simple: 10.

Un troll con un enorme garrote te sorprende.
¡El troll intenta atraparte!
¡El troll te golpea con un garrote!
¡El troll chilla de horror y huye!
Poder del troll con garrote: 20.
```

## Diagrama de clases

![alt text](./etc/decorator.urm.png "Decorator pattern class diagram")

## Aplicabilidad

Decorator se utiliza para:

* Añadir responsabilidades a objetos individuales de forma dinámica y transparente, es decir, sin
  afectar a otros objetos.
* Para responsabilidades que pueden ser retiradas.
* Cuando la extensión por subclase es poco práctica. A veces es posible un gran número de extensiones independientes
  son posibles y producirían una explosión de subclases para soportar cada combinación. O la definición de una clase
  puede estar oculta o no estar disponible para subclases.

## Tutoriales

* [Decorator Pattern Tutorial](https://www.journaldev.com/1540/decorator-design-pattern-in-java-example)

## Usos conocidos

* [java.io.InputStream](http://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html), [java.io.OutputStream](http://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html),
  [java.io.Reader](http://docs.oracle.com/javase/8/docs/api/java/io/Reader.html)
  y [java.io.Writer](http://docs.oracle.com/javase/8/docs/api/java/io/Writer.html)
* [java.util.Collections#synchronizedXXX()](http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedCollection-java.util.Collection-)
* [java.util.Collections#unmodifiableXXX()](http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#unmodifiableCollection-java.util.Collection-)
* [java.util.Collections#checkedXXX()](http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#checkedCollection-java.util.Collection-java.lang.Class-)

## Créditos

* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
* [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](https://www.amazon.com/gp/product/1937785467/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1937785467&linkCode=as2&tag=javadesignpat-20&linkId=7e4e2fb7a141631491534255252fd08b)
* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31)
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)
* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7)
* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=f27d2644fbe5026ea448791a8ad09c94)
