DECORATOR
PATTERN
What is Decorator?
-
A Decorator is an object which adds functionality to another object dynamically. It can be used to enhance the behavior of an object without requiring the author to reopen its class.
-
Also known as WRAPPER
When you need it ?
When you need to modifying existing systems where you may wish to add additional features to objects without the need to change the underlying code that uses them
CLASS DIAGRAM EXAMPLE
Without Decorator
With Decorator
PROBLEM STATEMENT
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
Without Decorator Pattern
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() {...};
...
Decorator Design Pattern
/*
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
WHY use DECORETOR PATTERN ?
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. |
REFERENCES
Decorator Pattern
By nur amirah
Decorator Pattern
- 278