您的位置:首页 > 其它

设计模式知识连载(31)---命令模式:

2017-12-27 11:25 706 查看
<body>

<h3>设计模式知识连载(31)---命令模式:</h3>
<p>
将请求与实现解耦并封装成独立对象,从而使不同的请求对客户端的实现参数化。
</p>

<hr>
<div>
<div id = 'title'></div>
<div id = 'product'></div>
</div>
<hr>
<br>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">

<script type="text/javascript">

/**
*   案例一:自由化创建视图,方式一:初始
*/
// 基本骨架
// var viewCommand = (function() {
//  // 方法集合
//  var Action = {
//      // 创建方法
//      create : function(){},

//      // 展示方法
//      display : function(){}
//  }

//  // 命令接口
//  return function excute() {}
// })() ;

// 具体实现
var viewCommand = (function() {
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('')
} ;

// 格式化字符串缓存字符串
var html = '' ;

// 格式化字符串 如:'<div>{#content#}</div>'用{content:'demo'}替换后可得到字符串:'<div>demo</div>'
function formateString(str, obj) {
// 替换'{#'与'#}'之间的字符串
return str.replace(/\{#(\w+)#\}/g, function(match, key) {
return obj[key] ;
}) ;
}

// 方法集合
var Action = {
// 创建方法
create : function(data, view){
// 解析数据,如果数据是一个数组
if(data.length) {
// 遍历数组
for(var i = 0; i < data.length; i++) {
html += formateString(tpl[view], data[i]) ;
}
}else{
// 直接格式化字符串缓存到HTML中
html += formateString(tpl[view], data) ;
}
},

// 展示方法
display : function(container, data, view) {
// 如果传入数据
if(data) {
// 根据给定数据创建视图
this.create(data, view) ;
}

// 展示模块
document.getElementById(container).innerHTML = html ;

// 展示后清空缓存的字符串
html = '' ;
}
}

// 命令接口
return function excute(msg) {
// 解析命令,如果msg.param不是数组则将其转化为数组(apply方法要求第二个参数为数组)
msg.param = Object.prototype.toString.call(msg.param) === '[object Array]' ? msg.param : [msg.param] ;

// Action内部调用的方法引用this,所以此处为保证作用域this执行传入Action
Action[msg.command].apply(Action, msg.param) ;
}
})() ;

// 模拟数据:
// 产品展示数据
var productData = [
{
src : 'command/02.jpg',
text : '绽放的桃花'
},
{
src : 'command/03.jpg',
text : '阳光下的温馨'
},
{
src : 'command/04.jpg',
text : '镜头前的绿色'
}
] ;

// 模块标题数据
var titleData = {
title : '夏日里的一片温馨',
tips : '暖暖的温情带给人们家的感受'
}

// 测试实例:
// 展示一个标题模块
viewCommand({
// 参数说明:方法-display
command : 'display',

// 参数说明:param1-元素容器,param2-标题数据,param3-元素模板,详见display方法
param : ['title', titleData, 'title']
}) ;
// 展示图片模块
viewCommand({
// 参数说明:方法-display
command : 'display',

// 参数说明:param1-元素容器,param2-标题数据,param3-元素模板,详见display方法
param : ['product', productData, 'product']
}) ;

// // 创建一个图片
// viewCommand({
//  command : 'create',
//  // 详见create方法参数
//  param : [{
//      src : 'command/01.jpg',
//      text : '迎着朝阳的野菊花'
//  }, 'product']
// }) ;
// // 创建后展示
// viewCommand({
//  command : 'display',
//  param : ['product', productData, 'product']
// }) ;

/**
*   案例二:绘图命令,方式一:初始
*/
// 实现对象
var CanvasCommand = (function() {
// 获取canvas
var canvas = document.getElementById("myCanvas");

// canvas元素的上下文引用对象缓存再命令对象的内部
var 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.strokeRect = c ;
},
// 描边矩形
strokeRect : 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不是一个数组,将其转化为数组(apply方法要求第二个参数为数组)
msg.param = Object.prototype.toString.call(msg.param) === '[object Array]' ? msg.param : [msg.param] ;
// Action内部调用的方法可能引用this,为保证作用域中this指向正确,故传入Action
Action[msg.command].apply(Action, msg.param) ;
}
}
}
})() ;

// 测试实例:
// 设置填充色彩为红色,并绘制一个矩形
CanvasCommand.excute([
{command : 'fillStyle', param : 'red'},
{command : 'fillRect', param : [20, 20, 100, 100]}
]) ;

</script>

</body>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息