2015-08-13 23:54:40 +02:00
---
layout: pattern
title: Decorator
folder: decorator
2015-08-15 18:03:05 +02:00
permalink: /patterns/decorator/
2015-08-20 21:40:07 +02:00
categories: Structural
2021-05-19 10:49:05 -06:00
language: en
2015-09-22 18:25:56 +05:30
tags:
2021-06-24 15:57:20 +03:00
- Gang of Four
2019-12-13 21:09:28 +02:00
- Extensibility
2015-08-13 23:54:40 +02:00
---
2016-01-03 21:14:30 +01:00
## Also known as
2020-08-29 16:49:45 +03:00
2016-01-03 21:14:30 +01:00
Wrapper
2015-11-04 21:13:32 +02:00
2016-01-03 21:14:30 +01:00
## Intent
2020-08-29 16:49:45 +03:00
Attach additional responsibilities to an object dynamically. Decorators provide a flexible
alternative to subclassing for extending functionality.
2015-08-13 23:54:40 +02:00
2017-09-02 23:10:39 +03:00
## Explanation
2021-06-24 15:57:20 +03:00
Real-world example
2017-09-02 23:10:39 +03:00
2021-06-24 15:57:20 +03:00
> There is an angry troll living in the nearby hills. Usually, it goes bare-handed but sometimes it
2020-08-29 16:49:45 +03:00
> has a weapon. To arm the troll it's not necessary to create a new troll but to decorate it
> dynamically with a suitable weapon.
2017-09-02 23:10:39 +03:00
In plain words
2020-08-29 16:49:45 +03:00
> Decorator pattern lets you dynamically change the behavior of an object at run time by wrapping
> them in an object of a decorator class.
2017-09-02 23:10:39 +03:00
Wikipedia says
2020-08-29 16:49:45 +03:00
> In object-oriented programming, the decorator pattern is a design pattern that allows behavior to
> be added to an individual object, either statically or dynamically, without affecting the behavior
> of other objects from the same class. The decorator pattern is often useful for adhering to the
> Single Responsibility Principle, as it allows functionality to be divided between classes with
> unique areas of concern.
2017-09-02 23:10:39 +03:00
**Programmatic Example**
2020-08-29 16:49:45 +03:00
Let's take the troll example. First of all we have a `SimpleTroll` implementing the `Troll`
interface:
2017-09-02 23:10:39 +03:00
2018-03-28 01:35:43 -04:00
```java
2017-09-02 23:10:39 +03:00
public interface Troll {
void attack();
int getAttackPower();
void fleeBattle();
}
2021-03-13 13:19:21 +01:00
@Slf4j
2017-09-02 23:10:39 +03:00
public class SimpleTroll implements Troll {
@Override
public void attack() {
LOGGER.info("The troll tries to grab you!");
}
@Override
public int getAttackPower() {
return 10;
}
@Override
public void fleeBattle() {
LOGGER.info("The troll shrieks in horror and runs away!");
}
}
```
2021-06-24 15:57:20 +03:00
Next, we want to add a club for the troll. We can do it dynamically by using a decorator:
2017-09-02 23:10:39 +03:00
2018-03-28 01:35:43 -04:00
```java
2021-03-13 13:19:21 +01:00
@Slf4j
2017-09-02 23:10:39 +03:00
public class ClubbedTroll implements Troll {
2020-07-30 20:28:47 +03:00
private final Troll decorated;
2017-09-02 23:10:39 +03:00
public ClubbedTroll(Troll decorated) {
this.decorated = decorated;
}
@Override
public void attack() {
decorated.attack();
LOGGER.info("The troll swings at you with a club!");
}
@Override
public int getAttackPower() {
return decorated.getAttackPower() + 10;
}
@Override
public void fleeBattle() {
decorated.fleeBattle();
}
}
```
2020-08-29 16:49:45 +03:00
Here's the troll in action:
2017-09-02 23:10:39 +03:00
2018-03-28 01:35:43 -04:00
```java
2017-09-02 23:10:39 +03:00
// simple troll
2021-06-24 15:57:20 +03:00
LOGGER.info("A simple looking troll approaches.");
2019-12-15 00:02:45 +05:30
var troll = new SimpleTroll();
2021-06-24 15:57:20 +03:00
troll.attack();
troll.fleeBattle();
LOGGER.info("Simple troll power: {}.\n", troll.getAttackPower());
2017-09-02 23:10:39 +03:00
// change the behavior of the simple troll by adding a decorator
2021-06-24 15:57:20 +03:00
LOGGER.info("A troll with huge club surprises you.");
2019-12-15 00:02:45 +05:30
var clubbedTroll = new ClubbedTroll(troll);
2021-06-24 15:57:20 +03:00
clubbedTroll.attack();
clubbedTroll.fleeBattle();
LOGGER.info("Clubbed troll power: {}.\n", clubbedTroll.getAttackPower());
2017-09-02 23:10:39 +03:00
```
2015-08-13 23:54:40 +02:00
2020-08-29 16:49:45 +03:00
Program output:
```java
2021-06-24 15:57:20 +03:00
A simple looking troll approaches.
2020-08-29 16:49:45 +03:00
The troll tries to grab you!
The troll shrieks in horror and runs away!
2021-06-24 15:57:20 +03:00
Simple troll power: 10.
A troll with huge club surprises you.
The troll tries to grab you!
The troll swings at you with a club!
2020-08-29 16:49:45 +03:00
The troll shrieks in horror and runs away!
2021-06-24 15:57:20 +03:00
Clubbed troll power: 20.
2020-08-29 16:49:45 +03:00
```
2019-12-07 20:01:13 +02:00
## Class diagram
2020-08-29 16:49:45 +03:00
2019-12-07 20:01:13 +02:00

2016-01-03 21:14:30 +01:00
## Applicability
2015-08-13 23:54:40 +02:00
2020-08-29 16:49:45 +03:00
Decorator is used to:
* Add responsibilities to individual objects dynamically and transparently, that is, without
affecting other objects.
* For responsibilities that can be withdrawn.
* When extension by subclassing is impractical. Sometimes a large number of independent extensions
are possible and would produce an explosion of subclasses to support every combination. Or a class
definition may be hidden or otherwise unavailable for subclassing.
2015-09-22 18:25:56 +05:30
2021-06-24 15:57:20 +03:00
## Tutorials
2020-08-29 16:49:45 +03:00
2017-09-23 20:55:38 -04:00
* [Decorator Pattern Tutorial ](https://www.journaldev.com/1540/decorator-design-pattern-in-java-example )
2021-06-24 15:57:20 +03:00
## Known uses
2020-08-29 16:49:45 +03:00
2016-08-20 20:49:28 +05:30
* [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 ) and [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- )
2016-08-20 20:57:48 +05:30
2016-08-20 20:49:28 +05:30
2016-01-03 21:14:30 +01:00
## Credits
2015-09-22 18:25:56 +05:30
2020-07-06 13:31:07 +03:00
* [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 )
2020-07-07 18:05:11 +03:00
* [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 )
2020-07-07 18:44:00 +03:00
* [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 )
2020-07-07 20:05:35 +03:00
* [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 )