javascript设计模式与开发实践阅读笔记(9)——命令模式
命令模式:有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么,此时希望用一种松耦合的方式来设计软件,使得请求发送者和请求接收者能够消除彼此之间的耦合关系。
说法很复杂,简单来说就是希望真正做事情的对象不要直接被调用,当我们下达一些命令之后, 希望对象已经间接的执行了。这样做的好处是可以解耦,代码可以更为灵活,还可以管理命令,甚至完成命令队列这样的操作。
实现思路
为了实现这种效果,我们需要通过一个函数,创造一个接口对象,调用接口对象的方法,就是调用对象真正的方法。
下面的例子是常规的直接调用对象的方法
var bindClick = function( button, func ){ //两个参数一个是执行对象,一个是执行的函数
button.onclick = func;
};
var MenuBar = {
refresh: function(){
console.log( '刷新界面' );
}
};
bindClick( button1, MenuBar.refresh );
//不直接写button1.click=function(){} 是因为在改动频繁的开发中,改动起来很麻烦,毕竟谁触发什么事件都是不确定的。
现在我们使用命令模式创建一个接口对象
var setCommand = function( button, command ){ //command为接口对象
button.onclick = function(){
command.refresh(); //接口对象提供的方法
}
};
var MenuBar = {
refresh: function(){
console.log( '刷新菜单界面' );
}
};
var createCommand = function( obj ){ //创建接口对象的方法
return {
refresh: function(){
obj.refresh();
}
}
};
var menubar = createCommand( MenuBar ); //创建一个接口对象
/*也可以这么写 或者方法放到原型上
var createCommand( obj ){
this.obj=obj;
this.refresh=function(){
this.obj.refresh();
}
}
var menubar = new createCommand( MenuBar );
*/
setCommand( button1, menubar ); //触发时调用接口对象的方法,接口对象再调用真正对象的方法。
从这里看好像和代理模式有点像,都是提供一个接口,内部做些处理再调用本体,但还是有区别的,代理模式的话代理对象只为一个本体服务,而命令模式中,接口对象就像一个黑盒子,可以依次执行命令,也能撤销命令,一个命令可能可以让不同的对象执行自己的方法,见下面的代码:
var list=(function(){ //接口对象,这里因为不存在通用的问题,所以直接写了
var arr=[];
return {
add:function(obj){
arr.push(obj);
},
execute:function(){
for(var i=0,l=arr.length;i<l;i++){
arr[i].execute();
}
}
}
})();
list.add( menubar );
list.add( headbar );
list.add( footbar );
list.execute();
上面这段代码就比较清晰了,命令的管理对象中的一个接口,可以执行不同对象的方法,等于导演说一句开机,剩下的人都可以自行其事。
这里我们假定对象都拥有一个execute方法,倘若对象没有一个公共的方法,那也可以给对象加一个,如果通过new的方式创建对象就在原型链上加,如果没有通过new,就直接添加
//new的方式
menubar=new Menubar();
Menubar.prototype.execute=function(){
this.refresh(); //真正需要执行的方法,下同
}
//直接加
menubar.execute=function(){
this.refresh();
}
撤销操作
撤销操作的实现一般是给命令对象增加一个名为unexecude或者undo的方法,在该方法里执行execute的反向操作。
比如动画,撤销时候回到一开始的位置,那就得记录一开始的位置,点撤销后回到那里;如果是canvas画图这种,撤销就是先清空画布,然后再把记录的命令依次执行,撤销那步除外。实现撤销要看具体情况。
总结
命令模式呢,就是通过一个对象来管理命令(需要执行的指令集合),通过这个对象,可以将原本复杂的对象间的交互变得简单起来。同时因为降低了耦合度,也有利于代码的维护。
javascript设计模式与开发实践阅读笔记(9)——命令模式的更多相关文章
- javascript设计模式与开发实践阅读笔记(4)——单例模式
定义 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 具体来说,就是保证有些对象有且只有一个,比如线程池.全局缓存.浏览器中的window 对象等.在js中单例模式用途很广,比如登录 ...
- javascript设计模式与开发实践阅读笔记(8)——观察者模式
发布-订阅模式,也叫观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 在JavaScript开发中,我们一般用事件模型来替代传统的观察者模式. ...
- javascript设计模式与开发实践阅读笔记(7)——迭代器模式
迭代器模式:指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. 迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺 ...
- javascript设计模式与开发实践阅读笔记(6)——代理模式
代理模式:是为一个对象提供一个代用品或占位符,以便控制对它的访问. 代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对 ...
- javascript设计模式与开发实践阅读笔记(5)——策略模式
策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 我的理解就是把各种方法封装成函数,同时存在一个可以调用这些方法的公共函数.这样做的好处是可以消化掉内部的分支判断,使代码效率 ...
- javascript设计模式与开发实践阅读笔记(11)—— 模板方法模式
模板方法模式: 由两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类.通常在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行顺序.子类通过继承这个抽象类,也继 ...
- JavaScript设计模式与开发实践——读书笔记1.高阶函数(上)
说来惭愧,4个多月未更新了.4月份以后就开始忙起来了,论文.毕设.毕业旅行等七七八八的事情占据了很多时间,毕业之后开始忙碌的工作,这期间一直想写博客,但是一直没能静下心写.这段时间在看<Java ...
- 《JavaScript设计模式与开发实践》笔记第八章 发布-订阅模式
第八章 发布-订阅模式 发布-订阅模式描述 发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 发布-订阅模式可以广泛应用于 ...
- JavaScript设计模式与开发实践——读书笔记1.高阶函数(下)
上部分主要介绍高阶函数的常见形式,本部分将着重介绍高阶函数的高级应用. 1.currying currying指的是函数柯里化,又称部分求值.一个currying的函数会先接受一些参数,但不立即求值, ...
随机推荐
- clang format 官方文档自定义参数介绍(中英文)
官方文档:http://clang.llvm.org/docs/ClangFormatStyleOptions.html 中文 在代码中配置样式 当使用 clang::format::reformat ...
- Java 容器:Collection 初探之 List
1 ///: JavaBasic//com.cnblogs.pattywgm.day1//CollectionTest.java 2 3 package com.cnblogs.pattywgm.da ...
- AngularJS学习--- AngularJS中XHR(AJAX)和依赖注入(DI) step5
前言:本文接前一篇文章,主要介绍什么是XHR,AJAX,DI,angularjs中如何使用XHR和DI. 1.切换工具目录 git checkout -f step- #切换分支 npm start ...
- Depth Bias 以及 Ogre材质中的depth_bias
深度偏移用来解决共面情况下出现闪烁的问题 通过给多边形增加一个z方向深度偏移(depth bias,z_bias),使3D空间的共面多边形看起来好像并不共面,以便它们能够被正确渲染.这种技术是很有用的 ...
- Eclipse CDT、MingGW 遇到的一些错误汇总
1.写代码时报错 "Member declaration not found" 如图: 在StackOverflow上找到的答案: 出问题的地方是 CDT的新功能 代码检查 Ope ...
- 【转】详解Python的装饰器
原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...
- Til the Cows Come Home
Description Bessie is out in the field and wants to get back to the barn to get as much sleep as pos ...
- Qt 无法解析外部文件2001,2019之类的
一般是部分代码出错,比如构造函数的实参没有对应或者设置好: 还有尝试删除debug生成的文件试试,清理当前项目->重新构建: 以及看下有没有变量没有初始化或者变量定义的时候父类错了等. 以及其他 ...
- 关系型数据库与NOSQL(转)
出处:http://www.cnblogs.com/chay1227/archive/2013/03/17/2964020.html 关系型数据库把所有的数据都通过行和列的二元表现形式表示出来. 关系 ...
- iOS开发零基础--Swift篇:逻辑分支
一. 分支的介绍 分支即if/switch/三目运算符等判断语句 通过分支语句可以控制程序的执行流程 二. if分支语句 和OC中if语句有一定的区别 判断句可以不加() 在Swift的判断句中必须有 ...