Skip to content

Commit

Permalink
#590 Add explanation to Decorator pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
iluwatar committed Sep 2, 2017
1 parent 6c9e005 commit 9d2f0c6
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 173 deletions.
91 changes: 90 additions & 1 deletion decorator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,96 @@ Attach additional responsibilities to an object dynamically.
Decorators provide a flexible alternative to subclassing for extending
functionality.

![alt text](./etc/decorator.png "Decorator")
## 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**

Lets take the troll example. First of all we have a simple troll implementing the troll interface

```
public interface Troll {
void attack();
int getAttackPower();
void fleeBattle();
}
public class SimpleTroll implements Troll {
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleTroll.class);
@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 club for the troll. We can do it dynamically by using a decorator

```
public class ClubbedTroll implements Troll {
private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class);
private 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

```
// simple troll
Troll troll = new SimpleTroll();
troll.attack(); // The troll tries to grab you!
troll.fleeBattle(); // The troll shrieks in horror and runs away!
// change the behavior of the simple troll by adding a decorator
Troll clubbed = new ClubbedTroll(troll);
clubbed.attack(); // The troll tries to grab you! The troll swings at you with a club!
clubbed.fleeBattle(); // The troll shrieks in horror and runs away!
```

## Applicability
Use Decorator
Expand Down
Binary file removed decorator/etc/decorator.png
Binary file not shown.
76 changes: 0 additions & 76 deletions decorator/etc/decorator.ucls

This file was deleted.

38 changes: 0 additions & 38 deletions decorator/etc/decorator.urm.puml

This file was deleted.

15 changes: 11 additions & 4 deletions decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,29 @@
/**
* Decorator that adds a club for the troll
*/
public class ClubbedTroll extends TrollDecorator {
public class ClubbedTroll implements Troll {

private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class);

private Troll decorated;

public ClubbedTroll(Troll decorated) {
super(decorated);
this.decorated = decorated;
}

@Override
public void attack() {
super.attack();
decorated.attack();
LOGGER.info("The troll swings at you with a club!");
}

@Override
public int getAttackPower() {
return super.getAttackPower() + 10;
return decorated.getAttackPower() + 10;
}

@Override
public void fleeBattle() {
decorated.fleeBattle();
}
}
53 changes: 0 additions & 53 deletions decorator/src/main/java/com/iluwatar/decorator/TrollDecorator.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
public class ClubbedTrollTest {

@Test
public void testSmartHostile() throws Exception {
public void testClubbedTroll() throws Exception {
// Create a normal troll first, but make sure we can spy on it later on.
final Troll simpleTroll = spy(new SimpleTroll());

Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@
<param>adapter</param>
<param>bridge</param>
<param>composite</param>
<param>decorator</param>
</skipForProjects>
</configuration>
</plugin>
Expand Down

0 comments on commit 9d2f0c6

Please sign in to comment.