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

<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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值