JS.Decorator
The JS.Decorator module gives you a means of implementing the decorator pattern
with minimal boilerplate and code duplication. When creating a decorator class, you
only need to define methods that differ in some way from the methods in the decorated
object (the component). This means you don’t have to write lots of forwarding methods
by hand, which saves you time, filesize, and reduces code duplication.
Let’s take a quick example:
// Basic Bike class. Bikes cost $10 per gear.
var Bike = new JS.Class({
initialize: function(model, gears) {
this.model = model;
this.gears = gears;
},
getModel: function() {
return this.model;
},
getPrice: function() {
return 10 * this.gears;
},
applyBrakes: function(force) {
// slow the bike down...
}
});
// Disk brake decorator. Disk brakes add to the price,
// and make the bike's brakes more powerful.
var DiskBrakeDecorator = new JS.Decorator(Bike, {
getPrice: function() {
return this.component.getPrice() + 50;
},
applyBrakes: function(force) {
this.component.applyBrakes(8 * force);
}
});
DiskBrakeDecorator gets versions of all Bike’s instance methods that forward the
method call onto the component and return the result. e.g., DiskBrakeDecorator’s
getModel() method looks like:
getModel: function() {
return this.component.getModel();
};
Any methods you don’t redefine in the decorator class will look similar to this. Let’s try our new classes out:
var bike = new Bike('Specialized Rock Hopper', 21);
bike.getPrice() // -> 210
bike = new DiskBrakeDecorator(bike);
bike.getPrice() // -> 260
bike.getModel() // -> "Specialized Rock Hopper"
Within your decorator methods, use this.component to refer to the decorated object.
If a decorator defines new methods, they will be passed through by any other decorators
you wrap an object with.
var HornDecorator = new JS.Decorator(Bike, {
beepHorn: function(noise) {
return noise.toUpperCase();
}
});
var bike = new Bike('Specialized Rock Hopper', 21);
// Let's wrap a HornDecorator with a DiskBrakeDecorator
bike = new HornDecorator(bike);
bike = new DiskBrakeDecorator(bike);
bike.beepHorn('beep!') // -> "BEEP!"