يعني إيه؟
زي القهوة بالإضافات - Milk, Sugar, Caramel! ☕
بتضيف features جديدة من غير ما تغير الـ Class الأصلي! 🎨
الـ Base interface - Coffee اللي عنده getCost() و getDescription().
بيغلف الـ Component وبيضيف functionality جديدة - زي الـ Milk أو Sugar!
كل Decorator عنده reference للـ Component اللي بيغلفه - Composition!
// ☕ Component Interface
class Coffee {
getCost() { throw "implement!"; }
getDescription() { throw "implement!"; }
}
// Concrete Component
class SimpleCoffee extends Coffee {
getCost() { return 5; }
getDescription() { return "☕ Simple Coffee"; }
}
// 🎨 Base Decorator
class CoffeeDecorator extends Coffee {
constructor(coffee) {
super();
this.coffee = coffee; // 🔗 Wrapping!
}
getCost() { return this.coffee.getCost(); }
getDescription() { return this.coffee.getDescription(); }
}
// Concrete Decorators
class MilkDecorator extends CoffeeDecorator {
getCost() { return this.coffee.getCost() + 2; }
getDescription() { return this.coffee.getDescription() + " + 🥛 Milk"; }
}
class CaramelDecorator extends CoffeeDecorator {
getCost() { return this.coffee.getCost() + 3; }
getDescription() { return this.coffee.getDescription() + " + 🍬 Caramel"; }
}
class WhipDecorator extends CoffeeDecorator {
getCost() { return this.coffee.getCost() + 1; }
getDescription() { return this.coffee.getDescription() + " + 🍦 Whip"; }
}
// 🎯 Stack decorators!
let coffee = new SimpleCoffee();
console.log(coffee.getDescription()); // ☕ Simple Coffee
console.log(coffee.getCost()); // 5
// Add Milk
coffee = new MilkDecorator(coffee);
console.log(coffee.getDescription()); // ☕ Simple Coffee + 🥛 Milk
console.log(coffee.getCost()); // 7
// Add Caramel
coffee = new CaramelDecorator(coffee);
console.log(coffee.getDescription()); // ☕ Simple Coffee + 🥛 Milk + 🍬 Caramel
console.log(coffee.getCost()); // 10
// ✅ Dynamic! بنضيف features at runtime!
// ✅ Open/Closed Principle - مش بنغير الـ SimpleCoffee!
Simple Coffee
$5