aka Wrapper (Adapter Pattern is also known as Wrapper)
based on aggregation or composition
It lets you dynamically change the behavior of an object at run time by wrapping them in an object of a decorator class.
Examples:
java.util.Collections.unmodifiableList(List)
convert list to unmodifiable list
the methods that would change the list throw an UnsupportedOperationException
java.util.Collections.synchronizedList(List)
access to the list elements are synchronized and not accessible via multiple threads simultaneously.
java.io.BufferedReader(FileReader)
General Syntax:
var a = new Component();var b = new Decorator1(a);var c = new Decorator2(b);c.execute();
Implementation
interface Giant { void attack(); int getAttackPower();}class SimpleGiant implements Giant { @Override public void attack() { System.out.println("The giant tries to grab you!"); } @Override public int getAttackPower() { return 10; }}class GiantAxeDecorator implements Giant { private final Giant decorated; public GiantAxeDecorator(Giant decorated) { this.decorated = decorated; } @Override public void attack() { decorated.attack(); System.out.println("The giant swings at you with an axe!"); } @Override public int getAttackPower() { return decorated.getAttackPower() + 10; }}
Driver
public class Test { public static void main(String[] args) { var giant = new SimpleGiant(); var giantWithAxe = new GiantAxeDecorator(giant); giantWithAxe.attack(); // The giant tries to grab you! // The giant swings at you with an axe! System.out.println(giantWithAxe.getAttackPower()); // 20 }}