--- layout: pattern title: Decorator folder: decorator permalink: /patterns/decorator/ categories: Structural language: en tags: - Gang of Four - Extensibility --- ## Also known as Wrapper ## Intent Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. ## Explanation Real-world example > There is an angry troll living in the nearby hills. Usually, it goes bare-handed but sometimes it > 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. In plain words > Decorator pattern lets you dynamically change the behavior of an object at run time by wrapping > them in an object of a decorator class. Wikipedia says > 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. **Programmatic Example** Let's take the troll example. First of all we have a `SimpleTroll` implementing the `Troll` interface: ```java public interface Troll { void attack(); int getAttackPower(); void fleeBattle(); } @Slf4j 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!"); } } ``` Next, we want to add a club for the troll. We can do it dynamically by using a decorator: ```java @Slf4j public class ClubbedTroll implements Troll { private final Troll decorated; 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(); } } ``` Here's the troll in action: ```java // simple troll LOGGER.info("A simple looking troll approaches."); var troll = new SimpleTroll(); troll.attack(); troll.fleeBattle(); LOGGER.info("Simple troll power: {}.\n", troll.getAttackPower()); // change the behavior of the simple troll by adding a decorator LOGGER.info("A troll with huge club surprises you."); var clubbedTroll = new ClubbedTroll(troll); clubbedTroll.attack(); clubbedTroll.fleeBattle(); LOGGER.info("Clubbed troll power: {}.\n", clubbedTroll.getAttackPower()); ``` Program output: ```java A simple looking troll approaches. The troll tries to grab you! The troll shrieks in horror and runs away! 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! The troll shrieks in horror and runs away! Clubbed troll power: 20. ``` ## Class diagram ![alt text](./etc/decorator.urm.png "Decorator pattern class diagram") ## Applicability 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. ## Tutorials * [Decorator Pattern Tutorial](https://www.journaldev.com/1540/decorator-design-pattern-in-java-example) ## Known uses * [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-) ## Credits * [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)