Decorator Design Pattern
Decorator Pattern
- structural design pattern
- aims to promote code re-use
- alternative to sub-classing
add (decorate) properties/methods to a base object
var Hobbit = function(){
//...
};
var HobbitWithRing = function(){},
HobbitWithSword = function(){},
HobbitWithRingAndSword = function(){},
HobbitWithShoes = function(){},
HobbitWithShoesAndRing = function(){},
HobbitWithShoesAndRingAndSword = function(){},
HobbitWithShoesAndSword = function(){};
From this ---^
var Hobbit = function(){
//...
};
Hobbit.prototype.equipment = function() {
return [];
};
// Decorator A
function Ring(hobbit) {
var currentEquipment = hobbit.equipment();
hobbit.equipment = function() {
return currentEquipment.concat(['ring']);
};
return hobbit;
}
// Decorator B
function Sword(hobbit) {
var currentEquipment = hobbit.equipment();
hobbit.equipment = function() {
return currentEquipment.concat(['sword']);
};
return hobbit;
}
// Here's one way of using it
var hobbit = new Sword(new Ring(new Hobbit ()));
console.log('hobbit.equipment', hobbit.equipment());
// Here's another
var hobbit2 = new Hobbit();
hobbit2 = new Ring(hobbit2);
hobbit2 = new Sword(hobbit2);
console.log('hobbit2.equipment', hobbit2.equipment());To this --->
Pros & Cons
- avoids need to rely on a large number of subclasses
- objects can be wrapped/"decorated" with new behavior
- base object won't be modified
- con: can complicate the process of instantiating the component (have to wrap it in a number of decorators in addition to instantiating the component)
Decorator Demo
// Class to be decorated
function Coffee() {
}
Coffee.prototype.cost = function() {
return 1;
};
// Decorator A
function Milk(coffee) {
var currentCost = coffee.cost();
coffee.cost = function() {
return currentCost + 0.5;
};
return coffee;
}
// Decorator B
function Whip(coffee) {
var currentCost = coffee.cost();
coffee.cost = function() {
return currentCost + 0.7;
};
return coffee;
}
// Decorator C
function Sprinkles(coffee) {
var currentCost = coffee.cost();
coffee.cost = function() {
return currentCost + 0.2;
};
return coffee;
}
// Here's one way of using it
var coffee = new Milk(new Whip(new Sprinkles(new Coffee())));
alert( coffee.cost() );
// Here's another
var coffee = new Coffee();
coffee = new Sprinkles(coffee);
coffee = new Whip(coffee);
coffee = new Milk(coffee);
alert(coffee.cost());Decorator Pattern
By Jacqueline Wijaya
Decorator Pattern
- 417