Decorator = "Dynamically add new behavior to an object without modifying its class." Wrapping the original object in a decorator class that implements the same interface
Example: SimpleCoffee, CoffeeDecorator, MilkDecorator, SugarDecorator.
// Component
interface Coffee {
double cost();
}
// Concrete component
class SimpleCoffee implements Coffee {
public double cost() {
return 5;
}
}
// Decorator base class
abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
}
// Concrete decorators
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
public double cost() {
return coffee.cost() + 2;
}
}
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
public double cost() {
return coffee.cost() + 1;
}
}
How to use
Step 1: Create base object
Coffee coffee = new SimpleCoffee();
System.out.println(coffee.cost()); // 5
Step 2: Wrap with decorators
coffee = new MilkDecorator(coffee); // add milk
coffee = new SugarDecorator(coffee); // add sugar
System.out.println(coffee.cost()); // 5 + 2 + 1 = 8
Or you can
Coffee coffee = new SugarDecorator(
new MilkDecorator(
new SimpleCoffee()
)
);
System.out.println(coffee.cost()); // 8
Real-world usage examples
InputStream input = new BufferedInputStream(
new FileInputStream("file.txt"));
Adapter: use a old class into another new class, when call new method then call old method of old class inside.Factory Method:Bridgepattern:Compositepattern: File, Folder, List Interface