Imagine a scenario where we have a plain coffee . After that you just recall that you need to put some add-ons at customer’s choice. So you will need to give some add-ons like milk and whipped cream on the go.
Concrete Component
Superclass
Let PlainCoffee = function() {...};
// Subclasses with different features
Let PlainWithMilkCoffee = function() {...};
Let PlainWithVanillaCoffee = function() {...};
Let PlainWithWhipCoffee = function() {...};
Let PlainWithMilkwithWhipCoffee = function() {...};
Let PlainMilkWithWhipCoffee = function() {...};
Let PlainMilkWithWhipAndVanillaCoffee = function() {...};
...
/*
Coffee interface:
getCost()
getDescription()
*/
class SimpleCoffee{
getCost() {
return 10
}
getDescription() {
return 'Simple coffee'
}
}
class MilkCoffee {
constructor(coffee) {
this.coffee = coffee
}
getCost() {
return this.coffee.getCost() + 2
}
getDescription() {
return this.coffee.getDescription() + ', milk'
}
}
class WhipCoffee {
constructor(coffee) {
this.coffee = coffee
}
getCost() {
return this.coffee.getCost() + 5
}
getDescription() {
return this.coffee.getDescription() + ', whip'
}
}
class VanillaCoffee {
constructor(coffee) {
this.coffee = coffee
}
getCost() {
return this.coffee.getCost() + 3
}
getDescription() {
return this.coffee.getDescription() + ', vanilla'
}
}
//Lets make a coffee now
let someCoffee
someCoffee = new SimpleCoffee()
console.log(someCoffee.getDescription())// Simple Coffee
console.log(someCoffee.getCost())// 10
someCoffee = new MilkCoffee(someCoffee)
console.log(someCoffee.getDescription())// Simple Coffee, milk
console.log(someCoffee.getCost())// 12
someCoffee = new WhipCoffee(someCoffee)
console.log(someCoffee.getDescription())// Simple Coffee, milk, whip
console.log(someCoffee.getCost())// 17
someCoffee = new VanillaCoffee(someCoffee)
console.log(someCoffee.getDescription())// Simple Coffee, milk, whip, vanilla
console.log(someCoffee.getCost())// 20
FLEXIBLE Provide a flexible alternative to subclassing for extending functionality |
---|
BEHAVIOR MODIFICATION Allow behavior modification at runtime rather than going back into existing code and making changes |
PERMUTATION ISSUES Nice solution to permutation issues because you can wrap a component with any number of decorators |
Open/Closed principle Classes should be open for extension but closed for modification. |