Files
java-design-patterns/decorator/README.md
T
Ilkka Seppälä 4108f86177 docs: Prepare for new website launch (#2149)
* Changed database implementation. Removed static objects.

* Fix Logs

* Fix 40 errors from checkstyle plugin run. 139 left))

* Fix CacheStore errors from checkstyle plugin 107 left

* Fix last errors in checkstyle.

* Fix sonar issues

* Fix issues in VALIDATE phase

* Fix Bug with mongo connection. Used "Try with resources"

* Add test

* Added docker-compose for mongo db. MongoDb db work fixed.

* Provided missing tests

* Comments to start Application with mongo.

* Fix some broken links

* Remove extra space

* Update filename

* Fix some links in localization folders

* Fix link

* Update frontmatters

* Work on patterns index page

* Work on index page

* Fixes according PR comments. Mainly Readme edits.

* fix frontmatter

* add missing png

* Update pattern index.md

* Add index.md for Chinese translation

* update image paths

* update circuit breaker image paths

* Update image paths for localizations

* add generated puml

* Add missing image

* Update img file extensions

* Update the rest of the EN and ZH patterns to conform with the new website

Co-authored-by: Victor Zalevskii <zvictormail@gmail.com>
2022-10-23 16:29:49 +03:00

6.0 KiB

title, category, language, tags
title category language tags
Decorator Structural en
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:

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:

@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:

// 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:

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

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

Known uses

Credits