再起航,我的学习笔记之JavaScript设计模式21(命令模式)
命令模式
概念描述
命令模式(Command): 将请求与实现解耦并封装成独立的对象,从而使不同的请求对客户端的实现参数化
示例代码
命令模式我们可以看成是将创建模块的逻辑封装在一个对象里,这个对象提供一个参数化的请求接口,通过调用这个接口并传递一些参数实现调用命令对象内部中的一些方法。
对于命令模式来说,请求部分很简单,只需要按照给定的参数格式书写指令即可,所以实现部分封装才是重点,因为它要为请求部分提供所需方法。
下面我们来看一个具体的例子,我们通过命令模式来封装一个画布对象并实现调用命令对象在页面上画出一个长方形。
//实现对象
var CanvasCommand=(function(){
//获取canvas
var canvas=document.getElementById('canvas'),
//canvas元素的上下文引用对象缓存在命令对象的内部
ctx=canvas.getContext('2d');
//内部方法对象
var Action={
//填充色彩
fillStyle:function(c){
ctx.fillStyle=c;
},
//填充矩形
fillRect:function(x,y,width,height){
ctx.fillRect(x,y,width,height);
},
//描边色彩
strokeStyle:function(c){
ctx.strokeStyle=c;
},
//描边矩形
strikeRect:function(x,y,width,height){
ctx.strokeRect(x,y,width,height);
},
//填充字体
fillText:function(text,x,y){
ctx.fillText(text,x,y);
},
//开启路径
beginPath:function(){
ctx.beginPath();
},
//移动画笔触点
moveTo:function(x,y){
ctx.moveTo(x,y);
},
//画笔连线
lineTo:function(x,y){
ctx.lineTo(x,y);
},
//绘制弧线
arc:function(x,y,r,begin,end,dir){
ctx.arc(x,y,r,begin,end,dir);
},
//填充
fill:function(){
ctx.fill();
},
//描边
stroke:function(){
ctx.stroke();
}
}
return {
//命令接口
excute:function(msg){
//如果没有命令直接返回
if(!msg){
return;
}
//如果命令是一个数组,遍历执行多个命令
if(msg.length){
for(var i=0;i<msg.length;i++)
arguments.callee(msg[i]);
}else{
//执行一个命令
msg.param=Object.prototype.toString.call(msg.param)==="[object Array]"?msg.param:[msg.param];
Action[msg.command].apply(Action,msg.param);
}
}
}
})()
我们来调用一下在页面画一个红色的矩形
CanvasCommand.excute([
{command:'fillStyle',param:'red'},
{command:'fillRect',param:[20,20,250,150]}
])

我们看到现在有了这个对象,任何人想绘制图形都不需要依赖canvas了只要按照命令对象结构给出的命令格式,写一条命令即可
实例代码
那么在除了画布外在其他场景我们还能使用命令模式做什么呢?其实我们还可以使用命令模式实现自由的创建视图。
既然我们要做一个自由化创建的视图,那么我们肯定要动态展示不同的模块,所以创建元素这一需求就是变化的,因此创建元素方法、展示方法应该都被命令化
//命令实现模块
var viewCommand=(function(){
//方法集合
var Action={
//创建视图方法
create:function(){},
//展示视图方法
display:function(){}
}
return function excute(){}
})();
我们的命令对象框架已经搭建出来了,那么我们就要开始实现命令对象中的每一个方法了
由于创建视图的过程中如果单纯使用DOM操作拼凑页面的开销实在有些大,所以我们用格式化字符串模块来创建我们的视图页面
var viewCommand=(function(){
var Action={
create:function(data,view){
//解析数据如果是一个数组
if(data.length){
//遍历数组
for(var i=0;i<data.length;i++){
//将格式化之后的字符串缓存到html中
html+=formteString(tpl[view],data[i])
}
}else{
//直接格式化字符串缓存到html中
html+=formteString(tpl[view],data)
}
},
display:function(container,data,view){
if(data){
//根据指定数据创建视图
this.create(data,view);
}
document.getElementById('container').innerHTML=html;
//展示后清空缓存的字符串
html='';
}
}
var tpl={
product:[
//展示图片结构模板
'<div>',
'<img src="{#src#}"/>',
'<p>{#text#}</p>',
'</div>'
].join(''),
//展示标题结构模板
title:[
'<div class="title">',
'<div class="main">',
'<h2>{#title#}</h2>',
'<p>{#tips#}</p>',
'</div>',
'</div>'
].join('')
}
//格式化字符串缓存字符串
html='';
function formteString(str,obj){
return str.replace(/\{#(\w+)#}/g,function(match,key){
return obj[key]
})
}
命令接口
return function excute(msg){
//解析命令,如果msg.param不是数组则将其转化为数组
msg.param=Object.prototype.toString.call(msg.param)==="[object Array]"?
msg.param:[msg.param];
Action[msg.command].apply(Action,msg.param)
}
})();
好了现在我们的命令对象已经创建好了,我们来测试一下
//模拟图片展示数据,标题展示数据
var productData=[
{src:'img/HBuilder.png',text:'1'},
{src:'img/HBuilder.png',text:'2'},
{src:'img/HBuilder.png',text:'3'}],
titleData={title:'HBuilder',tips:'Hello HBuilder'};
//展示标题模块
viewCommand({
command:'display',
param:['title',titleData,'title']
})

//展示多张图片
viewCommand({
command:'display',
param:['product',productData,'product']
})

//创建图片
viewCommand({
command:'create',
param:[{src:'img/HBuilder.png',text:'Hello HBuilder'},'product']
})
//展示多张图片
viewCommand({
command:'display',
param:['product',productData,'product']
})

总结
命令模式是将执行的命令封装,解决命令的发起者与命令的执行者之间的耦合。每一条命令实质上是一个操作。
命令的使用者不必要了解命令的执行者(命令对象)的命令接口使如何实现的、命令是如何接受的。命令是如何执行的。所有的命令都被存储在命令对象中
命令模式的优点:
命令模式的优点是解决命令使用者之间的耦合。新的命令很容易加入到命令系统中供使用者使用。命令的使用具有一致性,多数的命令在一定程度上是简化操作方法的使用。
命令模式的缺点:
命令模式是对一些操作的封装,这就造成每执行一次操作就要调用命令对象增加了系统的复杂度
也谢谢大家看到这里:)如果你觉得我的分享还可以请点击推荐,分享给你的朋友让我们一起进步~
好了以上就是本次分享的全部内容,本次示例参考自JavaScript设计模式一书,让我们一点点积累一点点成长,希望对大家有所帮助。
欢迎转载,转载请注明作者,原文出处。
再起航,我的学习笔记之JavaScript设计模式21(命令模式)的更多相关文章
- 再起航,我的学习笔记之JavaScript设计模式08(建造者模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...
- 再起航,我的学习笔记之JavaScript设计模式09(原型模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...
- 再起航,我的学习笔记之JavaScript设计模式11(外观模式)
经过一段时间的学习与分享,我们对创建型设计模式已经有了一定的认识,未来的一段时间里我们将展开新的篇章,开始迈入结构性设计模式的学习. 结构性设计模式与创建型设计模式不同,结构性设计模式更偏向于关注如何 ...
- 再起航,我的学习笔记之JavaScript设计模式14(桥接模式)
桥接模式 桥接模式(Bridge): 在系统沿着多个维度变化的同时,又不增加其复杂度并已达到解耦 从定义上看桥接模式的定义十分难以理解,那么我们来通过示例来演示什么是桥接模式. 现在我们需要做一个导航 ...
- 再起航,我的学习笔记之JavaScript设计模式17(模板方法模式)
模板方法模式 由模板方法模式开始我们正式告别结构型设计模式,开始行为型设计模式的学习分享 行为型设计模式用于不同对象之间职责划分或算法抽象,行为型设计模式不仅仅涉及类和对象,还涉及类或对象之间的交流模 ...
- 再起航,我的学习笔记之JavaScript设计模式20(策略模式)
策略模式 策略模式(Strategy):将定义的一组算法封装起来,使其相互之间可以替换.封装的算法具有一定的独立性,不会随客户端变化而变化. 其实策略模式在我们生活中可应用的地方还是比较多的,比如在商 ...
- 再起航,我的学习笔记之JavaScript设计模式22(访问者模式)
访问者模式 概念介绍 访问者模式(Visitor): 针对于对象结构中的元素,定义在不改变该对象的前提下访问结构中元素的新方法 解决低版本IE兼容性 我们来看下面这段代码,这段代码,我们封装了一个绑定 ...
- 再起航,我的学习笔记之JavaScript设计模式24(备忘录模式)
备忘录模式 概念介绍 备忘录模式(Memento): 在不破坏对象的封装性的前提下,在对象之外捕获并保存该对象内部的状态以便日后对象使用或者对象恢复到以前的某个状态. 简易分页 在一般情况下我们需要做 ...
- 再起航,我的学习笔记之JavaScript设计模式25(迭代器模式)
迭代器模式 概念介绍 迭代器模式(Iterator): 在不暴露对象内部结构的同时,可以顺序地访问聚合对象内部的元素. 迭代器 程序中的循环是一种利器,循环语句也使我们程序开发更简洁高效,但是有时一遍 ...
随机推荐
- java垃圾回收过程
对于年轻代,刚开始创建的对象都是放置在eden区的,而将年轻代分成3个部分,主要是为了生命周期短的对象尽量留在年轻代.当eden区申请不到空间的时候,进行minorGC,把存活的对象拷贝到survio ...
- 浅谈JavaScript和DOM中的类数组对象
JavaScript是一门弱类型语言,它的数据类型分为两大类:简单数据类型(5种:Undefined.Null.Boolean.Number.String)和复杂数据类型(1种:Object).Obj ...
- null == undefined ?
最近在看<JavaScript高级程序设计>一书,书中讲到相等操作符(==)时说,要比较相等性之前,不能将 null 和 undefined 转换成其他任何值,但要记住 null == u ...
- windows下vue.js开发环境搭建教程
这篇文章主要为大家详细介绍了windows下vue.js开发环境搭建教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 最近,vue.js越来越火.在这样的大浪潮下,我也开始进入vue的学习行列中 ...
- [NOIP模拟赛]约会date LCA(顺便填坑)
这道题也算是厉害了,改了整整俩小时最后发现是深信的LCA打错了,悲伤啊!信仰崩塌了! 顺便复习LCA,给出模板 void init(){//p[i][j]表示i节点2^j的祖先 int j; for( ...
- javascript今生前世
事情得从一个chrome控制台中的无意打印说起. 众所周知,js共六种数据类型,string.number.undefined.boolean.object.null.当然javascript还准备了 ...
- 程序员从技术到项目管理PM--思维转变
对以往所做项目的经验做下总结,作为项目经理首先要对项目负责,思维要做下转变,要从项目全局角度考虑问题: 从个人成就到团队成就. 无论是做管理还是做技术,成就导向意识是优秀员工的基本素质.只有具 ...
- php基础函数
函数四要素:返回类型(php没有返回类型), 函数名,参数列表,函数体//php定义函数的方式 简单 例://function show(){// echo "狗头铡伺候" ...
- JS基础属性跟运算
小编这周学了JS函数基础知识跟运算!!下面就迫不及待跟大家分享一下 [switch case的结构写法] 结构写法:(略) 2注意事项: ①switch结构()中的表达式.可以使用各种js支持的数据类 ...
- Navicat查询哪些表有指定字段名
通常需要查询某个字段来自于哪张表,在navicat中没有直接查哪些表有指定字段名的功能,只能用sql来查. 1.(按字段名查表)查询哪些表有指定字段名(比如查字段名article_id)的SQL: S ...