主页 > 互联网  > 

javascript设计模式-观察者和命令

javascript设计模式-观察者和命令
观察者

是一种管理人与任务之间的关系的得力工具,实质就是你可以对程序中某个对象的状态进行观察,并且在其发生改变时能够得到通知。一般有两种实现方式推或拉,在这个过程中各方的职责如下:

订阅者可以订阅和退订,他们还要接收,并且可以在由人投送和自己收取之间进行选择;发布者负责投关,他们可以在送出和由人取之间进行选择; function Publisher() { this.subscribers = []; } //投送方法 Publisher.prototype.deliver = function(data) { this.subscribers.forEach( function(fn) { fn(data); } ); return this; }; //订阅方法 Function.prototype.subscribe = function(publisher) { var that = this; var alreadyExists = publisher.subscribers.some( function(el) { if ( el === that ) { return; } } ); if ( !alreadyExists ) { publisher.subscribers.push(this); } return this; }; //退订方法 Function.prototype.unsubscribe = function(publisher) { var that = this; publisher.subscribers = publisher.subscribers.filter( function(el) { if ( el !== that ) { return el; } } ); return this; }; var publisherObject = new Publisher; var observerObject = function(data) { // process data console.log(data); // unsubscribe from this publisher arguments.callee.unsubscribe(publisherObject); }; observerObject.subscribe(publisherObject); 动画 // Publisher API var Animation = function(o) { this.onStart = new Publisher,//三个可监视时刻 this.onComplete = new Publisher, this.onTween = new Publisher; }; Animation. method('fly', function() { // begin animation this.onStart.deliver(); for ( ... ) { // loop through frames // deliver frame number this.onTween.deliver(i); } // end animation this.onComplete.deliver(); }); // setup an account with the animation manager var Superman = new Animation({...config properties...}); // Begin implementing subscribers var putOnCape = function(i) { }; var takeOffCape = function(i) { }; putOnCape.subscribe(Superman.onStart); takeOffCape.subscribe(Superman.onComplete); // fly can be called anywhere Superman.fly(); // for instance: addEvent(element, 'click', function() { Superman.fly(); }); 事件监听器 var element = document.getElementById(‘a’); var fn1 = function(e) { // handle click }; var fn2 = function(e) { // do other stuff with click }; addEvent(element, ‘click’, fn1); addEvent(element, ‘click’, fn2); 命令

是一种封装方法调用的方式,命令模式与普通函数不同。它可以用来对方法调用进行参数化处理和传送,经这样处理过的方法调用可以在任何需要的时候执行。它也可以用来消除调用操作的对象和实现操作的对象之间的耦合。

它在创建用户界面时非常有用,特别是在需要不受限制的取消操作的时候。它还可以用来替代回调函数 ,因为它能够提高在对象间传递的操作的模块化程度。

这种模式适合JSP中的ACTION的实现,在一个ACITON中封装多个命令,如果只封装一个就没有多大意思了。

/* AdCommand interface. */ var AdCommand = new Interface('AdCommand', ['execute']); /* StopAd command class. */ var StopAd = function(adObject) { // implements AdCommand this.ad = adObject; }; StopAd.prototype.execute = function() { this.ad.stop(); }; /* StartAd command class. */ var StartAd = function(adObject) { // implements AdCommand this.ad = adObject; }; StartAd.prototype.execute = function() { this.ad.start(); }; /* Useage. 这种方式后,就把按钮和他需要调用的操作之间解耦了*/ var startCommand = new StartAd(action); var stopCommand = new StopAd(action); new UiButton('Start ', startCommand); new UiButton('Stop ', stopCommand); /*匿名函数的写法,省略了很多代码*/ function makeStart(adObject) { return function() { adObject.start(); }; } function makeStop(adObject) { return function() { adObject.stop(); }; } /* Implementation code. */ var startCommand = makeStart(ads[i]); var stopCommand = makeStop(ads[i]); startCommand(); stopCommand();

多数命令模式都由以下几种角色组成,客户创建命令,调用者执行命令,接收者在命令执行时执行相应的操作。

接口格式 var Command = new Interface('Command', ['execute']); Interface.ensureImplements(someCommand, Command); someCommand.execute(); if(typeof someCommand != 'function') { throw new Error('Command isn't a function'); } 命令对象格式 /* SimpleCommand, a loosely coupled, simple command class. */ var SimpleCommand = function(receiver) { // implements Command this.receiver = receiver; }; SimpleCommand.prototype.execute = function() { this.receiver.action(); }; /* ComplexCommand, a tightly coupled, complex command class. */ 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(); }; var openCommand = new MenuCommand(fileActions.open); var openMenuItem = new MenuItem('Open', openCommand); fileMenu.add(openMenuItem); 取消操作

这种操作其实就是把堆栈和excute相反的操作结合使用。

var MoveUp = function(cursor) { // implements ReversibleCommand this.cursor = cursor; }; MoveUp.prototype = { execute: function() { cursor.move(0, -10); }, undo: function() { cursor.move(0, 10); } };

标签:

javascript设计模式-观察者和命令由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“javascript设计模式-观察者和命令