tutorial, no_image, designpatterns,

Designpatterns - no_image

Upendra Upendra Follow Jan 23, 2025 · 2 mins read
Designpatterns - no_image
Share this

Decorator pattern

Decorator pattern is a design pattern that allows behavior to be added to an individual object, 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.

The Decorator design pattern solves problems like:

  • Responsibilities should be added to (and removed from) an object dynamically at run-time.
  • A flexible alternative to subclassing for extending functionality should be provided.
  • Client-specified embellishment of a core object by recursively wrapping it.

When using subclassing, different subclasses extend a class in different ways. But an extension is bound to the class at compile-time and can’t be changed at run-time.

Example

Suppose we have an interface - GameUnit:

public interface GameUnit {
    int attackPower();
    int health();
}

and base implementation of GameUnit interface - SimpleUnit:

public final class SimpleUnit implements GameUnit {
    
    private final int attackPower;
    private final int health;
    
    public SimpleUnit() {
        this(1, 1);
    }
    
    public SimpleUnit(int attackPower, int health) {
        this.attackPower = attackPower;
        this.health = health;
    }
    
    @Override
    public int attackPower() {
        return attackPower;
    }

    @Override
    public int health() {
        return health;
    }
}

And we need to make two different units, one with weapons and the other with armor. For this we use the decorator pattern:

public final class ArmoredUnit implements GameUnit {

    private final GameUnit gameUnit;
    private final int armorValue;

    public ArmoredUnit(GameUnit gameUnit) {
        this(gameUnit, 10);
    }

    public ArmoredUnit(GameUnit gameUnit, int armorValue) {
        this.gameUnit = gameUnit;
        this.armorValue = armorValue;
    }

    @Override
    public int attackPower() {
        return gameUnit.attackPower();
    }

    @Override
    public int health() {
        return gameUnit.health() + armorValue;
    }
}
public final class ArmedUnit implements GameUnit {

    private final GameUnit gameUnit;
    private final int weaponPower;
    
    public ArmedUnit(GameUnit gameUnit) {
        this(gameUnit, 10);
    }
    
    public ArmedUnit(GameUnit gameUnit, int weaponPower) {
        this.gameUnit = gameUnit;
        this.weaponPower = weaponPower;
    }
    
    @Override
    public int attackPower() {
        return gameUnit.attackPower() + weaponPower;
    }

    @Override
    public int health() {
        return gameUnit.health();
    }
}

And now we can decorate GameUnit:

public final class DecoratorExample {

    public void decoratorExample() {
        GameUnit gameUnit = new SimpleUnit();
        GameUnit armoredUnit = new ArmoredUnit(gameUnit, 10);
        GameUnit armedUnit = new ArmedUnit(gameUnit);

        System.out.println("GameUnit power = " + gameUnit.attackPower() + ", " + "health = " + gameUnit.health());
        System.out.println("ArmoredUnit power = " + armoredUnit.attackPower() + ", " + "health = " + armoredUnit.health());
        System.out.println("ArmedUnit power = " + armedUnit.attackPower() + ", " + "health = " + armedUnit.health());
    }
}

Output:

GameUnit power = 1, health = 1
ArmoredUnit power = 1, health = 11
ArmedUnit power = 11, health = 1

https://en.wikipedia.org/wiki/Decorator_pattern
https://sourcemaking.com/design_patterns/decorator
https://springframework.guru/gang-of-four-design-patterns/decorator-pattern/

credit goes to @swayangjit
Join Newsletter
Get the latest news right in your inbox. We never spam!
Upendra
Written by Upendra Follow
Hi, I am Upendra, the author in Human and machine languages,I don't know to how 3 liner bio works so just Connect with me on social sites you will get to know me better.