Decorator
The 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.
// In the browser JS.require('JS.Decorator', function(Decorator) { ... }); // In CommonJS var Decorator = require('jsclass/src/decorator').Decorator;
Let’s take a quick example:
// Basic Bike class. Bikes cost $10 per gear. var Bike = new 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 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 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!"