Design patterns
patterns9DecoratorPattern
- Path
- pkg8patterns/patterns9DecoratorPattern.java
- Package
- pkg8patterns
- Study order
- 9
- Run
- Single-file source launch
- Command
- java pkg8patterns/patterns9DecoratorPattern.java
There is no in-browser runner. This is the file from the curriculum, unchanged.
1package pkg8patterns;2 3/*4 * Decorator (Structural)5 * ----------------------6 * INTENT: attach additional responsibilities to an object dynamically, as a7 * flexible alternative to subclassing.8 * UML: Component <|-- ConcreteComponent and <|-- Decorator (wraps a Component).9 * PROS: add behavior at runtime; compose features; avoids subclass explosion.10 * CONS: many small wrapper objects; order can matter.11 * REAL-WORLD: java.io streams (BufferedReader wraps Reader), Collections.unmodifiableList.12 */13public class patterns9DecoratorPattern {14 15 interface Coffee { String desc(); double cost(); }16 17 static class Espresso implements Coffee {18 public String desc() { return "Espresso"; }19 public double cost() { return 2.0; }20 }21 22 // Base decorator wraps another Coffee23 static abstract class CoffeeDecorator implements Coffee {24 protected final Coffee inner;25 CoffeeDecorator(Coffee inner) { this.inner = inner; }26 }27 static class Milk extends CoffeeDecorator {28 Milk(Coffee c) { super(c); }29 public String desc() { return inner.desc() + " + Milk"; }30 public double cost() { return inner.cost() + 0.5; }31 }32 static class Sugar extends CoffeeDecorator {33 Sugar(Coffee c) { super(c); }34 public String desc() { return inner.desc() + " + Sugar"; }35 public double cost() { return inner.cost() + 0.25; }36 }37 38 public static void main(String[] args) {39 Coffee order = new Sugar(new Milk(new Espresso())); // stack decorators40 System.out.printf("%s = $%.2f%n", order.desc(), order.cost());41 }42}