命令模式

命令模式是一种封装方法调用的方式,它用来对方法进行参数化处理和传送,经这样处理方法可以在任何需要的时候执行。

适用于两种情况,一是消除调用操作的对象和实现操作的对象之间的耦合,二是在创建用户界面方面,特别是需要不受限的取消操作的时候。

缺点在于增加复杂度,难以调试,所以一般不要强用。

 

1.简单命令对象一般用来消除接收者和调用者的耦合

var SimpleCommand = function(receiver) { // implements Command

  this.receiver = receiver;

};

SimpleCommand.prototype.execute = function() {

  this.receiver.action();

};
var Command = new Interface('Command', ['execute']);

var Composite = new Interface('Composite', ['add', 'remove', 'getChild', 

  'getElement']);

var MenuObject = new Interface('MenuObject', ['show']);



/* MenuBar class, a composite. */



var MenuBar = function() { // implements Composite, MenuObject

  this.menus = {};

  this.element = document.createElement('ul');

  this.element.style.display = 'none';

};

MenuBar.prototype = {

  add: function(menuObject) {

    Interface.ensureImplements(menuObject, Composite, MenuObject);

    this.menus[menuObject.name] = menuObject;

    this.element.appendChild(this.menus[menuObject.name].getElement());

  },

  remove: function(name) {

    delete this.menus[name];

  },

  getChild: function(name) {

    return this.menus[name];

  },

  getElement: function() {

    return this.element;

  },

  

  show: function() {

    this.element.style.display = 'block';

    for(name in this.menus) { // Pass the call down the composite.

      this.menus[name].show();

    }

  }

};



/* Menu class, a composite. */



var Menu = function(name) { // implements Composite, MenuObject

  this.name = name;

  this.items = {};

  this.element = document.createElement('li');

  this.element.innerHTML = this.name;

  this.element.style.display = 'none';

  this.container = document.createElement('ul');

  this.element.appendChild(this.container);

};

Menu.prototype = {

  add: function(menuItemObject) {

    Interface.ensureImplements(menuItemObject, Composite, MenuObject);

    this.items[menuItemObject.name] = menuItemObject;

    this.container.appendChild(this.items[menuItemObject.name].getElement());

  },

  remove: function(name) {

    delete this.items[name];

  },

  getChild: function(name) {

    return this.items[name];

  },

  getElement: function() {

    return this.element;

  },

  

  show: function() {

    this.element.style.display = 'block';

    for(name in this.items) { // Pass the call down the composite.

      this.items[name].show();

    }

  }

};



/* MenuItem class, a leaf. */



var MenuItem = function(name, command) { // implements Composite, MenuObject

  Interface.ensureImplements(command, Command);

  this.name = name;

  this.element = document.createElement('li');

  this.element.style.display = 'none';

  this.anchor = document.createElement('a');

  this.anchor.href = '#'; // To make it clickable.

  this.element.appendChild(this.anchor);

  this.anchor.innerHTML = this.name;



  addEvent(this.anchor, 'click', function(e) { // Invoke the command on click.

    e.preventDefault(); 

    command.execute();

  });

};

MenuItem.prototype = {

  add: function() {},

  remove: function() {},

  getChild: function() {},

  getElement: function() {

    return this.element;

  },

  

  show: function() {

    this.element.style.display = 'block';

  }

};





/* MenuCommand class, a command object. */



var MenuCommand = function(action) { // implements Command

  this.action = action;

};

MenuCommand.prototype.execute = function() {

  this.action();

};





/* Implementation code. */



/* Receiver objects, instantiated from existing classes. */

var fileActions = new FileActions();

var editActions = new EditActions();

var insertActions = new InsertActions();

var helpActions = new HelpActions();



/* Create the menu bar. */

var appMenuBar = new MenuBar();



/* The File menu. */

var fileMenu = new Menu('File');



var openCommand = new MenuCommand(fileActions.open);

var closeCommand = new MenuCommand(fileActions.close);

var saveCommand = new MenuCommand(fileActions.save);

var saveAsCommand = new MenuCommand(fileActions.saveAs);



fileMenu.add(new MenuItem('Open', openCommand));

fileMenu.add(new MenuItem('Close', closeCommand));

fileMenu.add(new MenuItem('Save', saveCommand));

fileMenu.add(new MenuItem('Save As...', saveAsCommand));



appMenuBar.add(fileMenu);



/* The Edit menu. */

var editMenu = new Menu('Edit');



var cutCommand = new MenuCommand(editActions.cut);

var copyCommand = new MenuCommand(editActions.copy);

var pasteCommand = new MenuCommand(editActions.paste);

var deleteCommand = new MenuCommand(editActions.delete);



editMenu.add(new MenuItem('Cut', cutCommand));

editMenu.add(new MenuItem('Copy', copyCommand));

editMenu.add(new MenuItem('Paste', pasteCommand));

editMenu.add(new MenuItem('Delete', deleteCommand));



appMenuBar.add(editMenu);



/* The Insert menu. */

var insertMenu = new Menu('Insert');



var textBlockCommand = new MenuCommand(insertActions.textBlock);

insertMenu.add(new MenuItem('Text Block', textBlockCommand));



appMenuBar.add(insertMenu);



/* The Help menu. */

var helpMenu = new Menu('Help');



var showHelpCommand = new MenuCommand(helpActions.showHelp);

helpMenu.add(new MenuItem('Show Help', showHelpCommand));



appMenuBar.add(helpMenu);



/* Build the menu bar. */

document.getElementsByTagName('body')[0].appendChild(appMenuBar.getElement());

appMenuBar.show();





/* Adding more menu items later on. */



var imageCommand = new MenuCommand(insertActions.image);

insertMenu.add(new MenuItem('Image', imageCommand));

2.复杂命令对象一般用来封装不可分的或事务性的复杂指令,并没有接收者

var ComplexCommand = function() { // implements Command

  this.logger = new Logger();

  this.xhrHandler = XhrManager.createXhrHandler();

  this.parameters = {};

};

ComplexCommand.prototype = {

  setParameter: function(key, value) {

    this.parameters[key] = value;

  },

  execute: function() {

    this.logger.log('Executing command');

    var postArray = [];

    for(var key in this.parameters) {

      postArray.push(key + '=' + this.parameters[key]);

    }

    var postString = postArray.join('&');

    this.xhrHandler.request(

      'POST', 

      'script.php', 

      function() {}, 

      postString

    );

  }

};



/* GreyAreaCommand, somewhere between simple and complex. */



var GreyAreaCommand = function(recevier) { // implements Command

  this.logger = new Logger();

  this.receiver = receiver;

};

GreyAreaCommand.prototype.execute = function() {

  this.logger.log('Executing command');

  this.receiver.prepareAction();

  this.receiver.action();

};

你可能感兴趣的:(命令模式)