再起航,我的学习笔记之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): 在不暴露对象内部结构的同时,可以顺序地访问聚合对象内部的元素. 迭代器 程序中的循环是一种利器,循环语句也使我们程序开发更简洁高效,但是有时一遍 ...
随机推荐
- ASP.NET程序运行出现WebDev.WebServer40.exe已停止工作解决方法(netsh winsock reset)
问题描述:在开发系统时候运行程序突然报出"WebDev.WebServer40.exe已停止工作"的错误,程序调试运行,发现程序在打开数据库时候报错,也就是Connection.O ...
- hdu--1316--How Many Fibs?(java大数)
How Many Fibs? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码
前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 一点感想 很意外的,第一 ...
- react - 解刨组件的多种写法
一,原始的createClass写法 对于写react组件,很多人第一印象往往是createClass,这是因为createClass是react组件最原始的写法,基本每个学react的人都是接触这种 ...
- Appium入门示例(Java)
一.使用Eclipse直接创建案例工程 1.打开Eclipse,[File]-->[New]-->[Project] 2.选择[Java Project]-->[Next] 3.输入 ...
- AIX缩小逻辑卷报错chfs: 0506-964
--AIX缩小逻辑卷报错chfs: 0506-964 -----------------------------------------2013/10/29 通过smit chfs/或 chfs命令 ...
- 学习笔记TF041:分布式并行
TensorFlow分布式并行基于gRPC通信框架,一个master负责创建Session,多个worker负责执行计算图任务. 先创建TensorFlow Cluster对象,包含一组task(每个 ...
- 配置Tomcat
目前有很多网站使用jsp的程序编写,所以解析jsp的程序就必须要有相关的软件来完成.Tomcat就是用来解析jsp程序的一个软件. 安装tomcat Tomcat的安装分为两个步骤:安装JDK和安装T ...
- Tab选框
<html>代码 基本架构:一个大的div下面2个ul,ul下面各三个li <div class="big"> <ul class="con ...
- 复杂JSON反序列化为类对象
有3种常用的反序列化库,gson和fastjson都很棒,json-lib有很大的局限性不推荐使用! 1. net.sf.json(json-lib) 只能用于解析简单的JSON,稍微复杂点的例如,类 ...