03.09.2015 Views

Design Patterns

Download - Assembla

Download - Assembla

SHOW MORE
SHOW LESS
  • No tags were found...

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

238<br />

CHAPTER 16 ■ THE COMMAND PATTERN<br />

code for each UI class you create. If you want to use these commands as keyboard shortcuts,<br />

you have to implement the stack-pushing code again. A better solution is to wrap each command<br />

in a decorator that implements this code for you. You could then pass each command to<br />

whatever UI element you like, without worrying about the undo code.<br />

Here is a decorator that pushes the command to a stack before executing it:<br />

/* UndoDecorator class. */<br />

var UndoDecorator = function(command, undoStack) { // implements ReversibleCommand<br />

this.command = command;<br />

this.undoStack = undoStack;<br />

};<br />

UndoDecorator.prototype = {<br />

execute: function() {<br />

this.undoStack.push(this.command);<br />

this.command.execute();<br />

},<br />

undo: function() {<br />

this.command.undo();<br />

}<br />

};<br />

This is a great use of the decorator pattern. It allows you to add an extra feature to the<br />

commands while still maintaining the same interface. These decorator objects can be used<br />

interchangeably with all of the command objects in this example.<br />

Next come the UI classes; these create the necessary HTML elements and attach click<br />

listeners to them, which invoke either execute or undo:<br />

/* CommandButton class. */<br />

var CommandButton = function(label, command, parent) {<br />

Interface.ensureImplements(command, ReversibleCommand);<br />

this.element = document.createElement('button');<br />

this.element.innerHTML = label;<br />

parent.appendChild(this.element);<br />

addEvent(this.element, 'click', function() {<br />

command.execute();<br />

});<br />

};<br />

/* UndoButton class. */<br />

var UndoButton = function(label, parent, undoStack) {<br />

this.element = document.createElement('button');<br />

this.element.innerHTML = label;<br />

parent.appendChild(this.element);

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!