C++ This implementation (which uses C++23 features) is based on the pre C++98 implementation in the book. import std; using std::unique_ptr; // Beverage interface. class Beverage { public: virtual void drink() = 0; virtual ~Beverage() = default; }; // Drinks which can be decorated. class Coffee: public Beverage { public: virtual void drink() override { std::print("Drinking Coffee"); } }; class Soda: public Beverage { public: virtual void drink() override { std::print("Drinking Soda"); } }; class BeverageDecorator: public Beverage { private: unique_ptr component; protected: void callComponentDrink() { if (component) { component->drink(); } } public: BeverageDecorator() = delete; explicit BeverageDecorator(unique_ptr component): component{std::move(component)} {} virtual void drink() = 0; }; class Milk: public BeverageDecorator { private: float percentage; public: Milk(unique_ptr component, float percentage): BeverageDecorator(std::move(component)), percentage{percentage} {} virtual void drink() override { callComponentDrink(); std::print(", with milk of richness {}%", percentage); } }; class IceCubes: public BeverageDecorator { private: int count; public: IceCubes(unique_ptr component, int count): BeverageDecorator(std::move(component)), count{count} {} virtual void drink() override { callComponentDrink(); std::print(", with {} ice cubes", count); } }; class Sugar: public BeverageDecorator { private: int spoons = 1; public: Sugar(unique_ptr component, int spoons): BeverageDecorator(std::move(component)), spoons{spoons} {} virtual void drink() override { callComponentDrink(); std::print(", with {} spoons of sugar", spoons); } }; int main(int argc, char* argv[]) { unique_ptr soda = std::make_unique(); soda = std::make_unique(std::move(soda), 3); soda = std::make_unique(std::move(soda), 1); soda->drink(); std::println(); unique_ptr coffee = std::make_unique(); coffee = std::make_unique(std::move(coffee), 16); coffee = std::make_unique(std::move(coffee), 3.); coffee = std::make_unique(std::move(coffee), 2); coffee->drink(); return 0; } The program output is like Drinking Soda, with 3 ice cubes, with 1 spoons of sugar Drinking Coffee, with 16 ice cubes, with milk of richness 3%, with 2 spoons of sugar Full example can be tested on a godbolt page.
C++ Two options are presented here: first, a dynamic, runtime-composable decorator (has issues with calling decorated functions unless proxied explicitly) and a decorator that uses mixin inheritance.
Dynamic decorator import std; using std::string; class Shape { public: virtual ~Shape() = default; virtual string getName() const = 0; }; class Circle: public Shape { private: float radius = 10.0f; public: void resize(float factor) noexcept { radius *= factor; }
nodiscard string getName() const override { return std::format("A circle of radius {}", radius); } }; class ColoredShape: public Shape { private: string color; Shape& shape; public: ColoredShape(const string& color, Shape& shape): color{color}, shape{shape} {}
nodiscard string getName() const override { return std::format("{} which is colored {}", shape.getName(), color); } }; int main() { Circle circle; ColoredShape coloredShape{"red", circle}; std::println("{}", coloredShape.getName()); } import std; using std::string; using std::unique_ptr; class WebPage { public: virtual void display() = 0; virtual ~WebPage() = default; }; class BasicWebPage: public WebPage { private: string html; public: void display() override { std::println("Basic WEB page"); } }; class WebPageDecorator: public WebPage { private: unique_ptr webPage; public: explicit WebPageDecorator(unique_ptr webPage): webPage{std::move(webPage)} {} void display() override { webPage->display(); } }; class AuthenticatedWebPage: public WebPageDecorator { public: explicit AuthenticatedWebPage(unique_ptr webPage): WebPageDecorator(std::move(webPage)) {} void authenticateUser() { std::println("authentication done"); } void display() override { authenticateUser(); WebPageDecorator::display(); } }; class AuthorizedWebPage: public WebPageDecorator { public: explicit AuthorizedWebPage(unique_ptr webPage): WebPageDecorator(std::move(webPage)) {} void authorizedUser() { std::println("authorized done"); } void display() override { authorizedUser(); WebPageDecorator::display(); } }; int main(int argc, char* argv[]) { unique_ptr myPage = std::make_unique(); myPage = std::make_unique(std::move(myPage)); myPage = std::make_unique(std::move(myPage)); myPage->display(); std::println(); return 0; }
Static decorator (mixin inheritance) This example demonstrates a static Decorator implementation, which is possible due to C++ ability to inherit from the template argument. import std; using std::string; class Circle { private: float radius = 10.0f; public: void resize(float factor) noexcept { radius *= factor; }
nodiscard string getName() const { return std::format("A circle of radius {}", radius); } }; template class ColoredShape: public T { private: string color; public: explicit ColoredShape(const string& color): color{color} {}
nodiscard string getName() const { return std::format("{} which is colored {}", T::getName(), color); } }; int main() { ColoredShape redCircle{"red"}; std::println("{}", redCircle.getName()); redCircle.resize(1.5f); std::println("{}", redCircle.getName()); }
Java First example (window/scrolling scenario) The following Java example illustrates the use of decorators using the window/scrolling scenario. // The Window interface class public interface Window { void draw(); // Draws the Window String getDescription(); // Returns a description of the Window } // Implementation of a simple Window without any scrollbars class SimpleWindow implements Window { @Override public void draw() { // Draw window } @Override public String getDescription() { return "simple window"; } } The following classes contain the decorators for all Window classes, including the decorator classes themselves. // abstract decorator class - note that it implements Window abstract class WindowDecorator implements Window { private final Window windowToBeDecorated; // the Window being decorated public WindowDecorator(Window windowToBeDecorated) { this.windowToBeDecorated = windowToBeDecorated; } @Override public void draw() { windowToBeDecorated.draw(); // Delegation } @Override public String getDescription() { return windowToBeDecorated.getDescription(); // Delegation } } // The first concrete decorator which adds vertical scrollbar functionality class VerticalScrollBarDecorator extends WindowDecorator { public VerticalScrollBarDecorator(Window windowToBeDecorated) { super(windowToBeDecorated); } @Override public void draw() { super.draw(); drawVerticalScrollBar(); } private void drawVerticalScrollBar() { // Draw the vertical scrollbar } @Override public String getDescription() { return String.format("%s, including vertical scrollbars", super.getDescription()); } } // The second concrete decorator which adds horizontal scrollbar functionality class HorizontalScrollBarDecorator extends WindowDecorator { public HorizontalScrollBarDecorator(Window windowToBeDecorated) { super(windowToBeDecorated); } @Override public void draw() { super.draw(); drawHorizontalScrollBar(); } private void drawHorizontalScrollBar() { // Draw the horizontal scrollbar } @Override public String getDescription() { return String.format("%s, including horizontal scrollbars", super.getDescription()); } } Here is a test program that creates a Window instance which is fully decorated (i.e., with vertical and horizontal scrollbars), and prints its description: public class DecoratedWindowTest { public static void main(String[] args) { // Create a decorated Window with horizontal and vertical scrollbars Window decoratedWindow = new HorizontalScrollBarDecorator ( new VerticalScrollBarDecorator(new SimpleWindow()) ); // Print the Window's description System.out.println(decoratedWindow.getDescription()); } } The output of this program is "simple window, including vertical scrollbars, including horizontal scrollbars". Notice how the getDescription method of the two decorators first retrieve the decorated Window's description and
decorates it with a suffix. Below is the JUnit test class for the Test Driven Development import org.junit.Assert; import org.junit.Test; public class WindowDecoratorTest { @Test public void testWindowDecoratorTest() { Window decoratedWindow = new HorizontalScrollBarDecorator( new VerticalScrollBarDecorator(new SimpleWindow()) ); // assert that the description indeed includes horizontal + vertical scrollbars Assert.assertEquals("simple window, including vertical scrollbars, including horizontal scrollbars", decoratedWindow.getDescription()); } }
Second example (coffee making scenario) The next Java example illustrates the use of decorators using coffee making scenario. In this example, the scenario only includes cost and ingredients. // The interface Coffee defines the functionality of Coffee implemented by decorator public interface Coffee { public double getCost(); // Returns the cost of the coffee public String getIngredients(); // Returns the ingredients of the coffee } // Extension of a simple coffee without any extra ingredients public class SimpleCoffee implements Coffee { @Override public double getCost() { return 1; } @Override public String getIngredients() { return "Coffee"; } } The following classes contain the decorators for all classes, including the decorator classes themselves. // Abstract decorator class - note that it implements Coffee interface public abstract class CoffeeDecorator implements Coffee { private final Coffee decoratedCoffee; public CoffeeDecorator(Coffee c) { this.decoratedCoffee = c; } @Override public double getCost() { // Implementing methods of the interface return decoratedCoffee.getCost(); } @Override public String getIngredients() { return decoratedCoffee.getIngredients(); } } // Decorator WithMilk mixes milk into coffee. // Note it extends CoffeeDecorator. class WithMilk extends CoffeeDecorator { public WithMilk(Coffee c) { super(c); } @Override public double getCost() { // Overriding methods defined in the abstract superclass return super.getCost() + 0.5; } @Override public String getIngredients() { return String.format("%s, Milk", super.getIngredients()); } } // Decorator WithSprinkles mixes sprinkles onto coffee. // Note it extends CoffeeDecorator. class WithSprinkles extends CoffeeDecorator { public WithSprinkles(Coffee c) { super(c); } @Override public double getCost() { return super.getCost() + 0.2; } @Override public String getIngredients() { return String.format("%s, Sprinkles", super.getIngredients()); } } Here's a test program that creates a instance which is fully decorated (with milk and sprinkles), and calculate cost of coffee and prints its ingredients: public class Main { public static void printInfo(Coffee c) { System.out.printf("Cost: %s; Ingredients: %s%n", c.getCost(), c.getIngredients()); } public static void main(String[] args) { Coffee c = new SimpleCoffee(); printInfo(c); c = new WithMilk(c); printInfo(c); c = new WithSprinkles(c); printInfo(c); } } The output of this program is given below: Cost: 1.0; Ingredients: Coffee Cost: 1.5; Ingredients: Coffee, Milk Cost: 1.7; Ingredients: Coffee, Milk, Sprinkles
PHP abstract class Component { protected $data; protected $value; abstract public function getData(); abstract public function getValue(); } class ConcreteComponent extends Component { public function __construct() { $this->value = 1000; $this->data = "Concrete Component:\t{$this->value}\n"; } public function getData() { return $this->data; } public function getValue() { return $this->value; } } abstract class Decorator extends Component { } class ConcreteDecorator1 extends Decorator { public function __construct(Component $data) { $this->value = 500; $this->data = $data; } public function getData() { return $this->data->getData() . "Concrete Decorator 1:\t{$this->value}\n"; } public function getValue() { return $this->value + $this->data->getValue(); } } class ConcreteDecorator2 extends Decorator { public function __construct(Component $data) { $this->value = 500; $this->data = $data; } public function getData() { return $this->data->getData() . "Concrete Decorator 2:\t{$this->value}\n"; } public function getValue() { return $this->value + $this->data->getValue(); } } class Client { private $component; public function __construct() { $this->component = new ConcreteComponent(); $this->component = $this->wrapComponent($this->component); echo $this->component->getData(); echo "Client:\t\t\t"; echo $this->component->getValue(); } private function wrapComponent(Component $component) { $component1 = new ConcreteDecorator1($component); $component2 = new ConcreteDecorator2($component1); return $component2; } } $client = new Client(); // Result: #quanton81 //Concrete Component: 1000 //Concrete Decorator 1: 500 //Concrete Decorator 2: 500 //Client: 2000
Python The following Python example, taken from Python Wiki - DecoratorPattern, shows us how to pipeline decorators to dynamically add many behaviors in an object: """ Demonstrated decorators in a world of a 10x10 grid of values 0–255. """ import random from typing import Any def s32_to_u16(x: int) -> int: sign: int if x int: return s32_to_u16(x) | (s32_to_u16(y) None: self.seed_modifier: int = seed_modifier def get(self, x: int, y: int) -> int: seed: int = seed_from_xy(x, y) ^ self.seed_modifier random.seed(seed) return random.randint(0, 255) class DataSquare: def __init__(self, initial_value: int = None) -> None: self.data: list[int] = [initial_value] * 10 * 10 def get(self, x: int, y: int) -> int: return self.data[(y * 10) + x] # yes: these are all 10x10 def set(self, x: int, y: int, u: int) -> None: self.data[(y * 10) + x] = u class CacheDecorator: def __init__(self, decorated: Any) -> None: self.decorated: Any = decorated self.cache: DataSquare = DataSquare() def get(self, x: int, y: int) -> int: if self.cache.get(x, y) == None: self.cache.set(x, y, self.decorated.get(x, y)) return self.cache.get(x, y) class MaxDecorator: def __init__(self, decorated: Any, max: int) -> None: self.decorated: Any = decorated self.max: int = max def get(self, x: int, y: int) -> None: if self.decorated.get(x, y) > self.max: return self.max return self.decorated.get(x, y) class MinDecorator: def __init__(self, decorated: Any, min: int) -> None: self.decorated: Any = decorated self.min: int = min def get(self, x: int, y: int) -> int: if self.decorated.get(x, y) None: self.decorated: Any = decorated def get(self, x: int, y: int) -> int: return self.decorated.get(x, y) def draw(self) -> None: for y in range(10): for x in range(10): print("%3d" % self.get(x, y), end=' ') print() if __name__ == "__main__": # Now, build up a pipeline of decorators: random_square: RandomSquare = RandomSquare(635) random_cache: CacheDecorator = CacheDecorator(random_square) max_filtered: MaxDecorator = MaxDecorator(random_cache, 200) min_filtered: MinDecorator = MinDecorator(max_filtered, 100) final: VisibilityDecorator = VisibilityDecorator(min_filtered) final.draw()
Note: The Decorator Pattern (or an implementation of this design pattern in Python - as the above example) should not be confused with
Python Decorators, a language feature of Python. They are different things. Second to the Python Wiki: The Decorator Pattern is a pattern described in the Design Patterns Book. It is a way of apparently modifying an object's behavior, by enclosing it inside a decorating object with a similar interface. This is not to be confused with Python Decorators, which is a language feature for dynamically modifying a function or class.
Crystal abstract class Coffee abstract def cost abstract def ingredients end • Extension of a simple coffee class SimpleCoffee Output: Cost: 1.0; Ingredients: Coffee Cost: 1.5; Ingredients: Coffee, Milk Cost: 1.7; Ingredients: Coffee, Milk, Sprinkles
C# namespace Wikipedia.Examples; interface IBike { string GetDetails(); double GetPrice(); } class AluminiumBike : IBike { public double GetPrice() => 100.0; public string GetDetails() => "Aluminium Bike"; } class CarbonBike : IBike { public double GetPrice() => 1000.0; public string GetDetails() => "Carbon"; } abstract class BikeAccessories : IBike { private readonly IBike _bike; public BikeAccessories(IBike bike) { _bike = bike; } public virtual double GetPrice() => _bike.GetPrice(); public virtual string GetDetails() => _bike.GetDetails(); } class SecurityPackage : BikeAccessories { public SecurityPackage(IBike bike) : base(bike) { // ... } public override string GetDetails() => $"{base.GetDetails()} + Security Package"; public override double GetPrice() => base.GetPrice() + 1; } class SportPackage : BikeAccessories { public SportPackage(IBike bike) : base(bike) { // ... } public override string GetDetails() => $"{base.GetDetails()} + Sport Package"; public override double GetPrice() => base.GetPrice() + 10; } public class BikeShop { public void UpgradeBike() { AluminiumBike basicBike = new AluminiumBike(); BikeAccessories upgraded = new SportPackage(basicBike); upgraded = new SecurityPackage(upgraded); Console.WriteLine($"Bike: '{upgraded.GetDetails()}' Cost: {upgraded.GetPrice()}"); } static void Main(string[] args) { UpgradeBike(); } } Output: Bike: 'Aluminium Bike + Sport Package + Security Package' Cost: 111
Ruby class AbstractCoffee def print puts "Cost: #{cost}; Ingredients: #{ingredients}" end end class SimpleCoffee Output: Cost: 1.0; Ingredients: Coffee Cost: 1.5; Ingredients: Coffee, Milk Cost: 1.7; Ingredients: Coffee, Milk, Sprinkles ==See also==