深入理解JavaScript系列(34):设计模式之命令模式详解


Posted in Javascript onMarch 03, 2015

介绍

命令模式(Command)的定义是:用于将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及执行可撤销的操作。也就是说改模式旨在将函数的调用、请求和操作封装成一个单一的对象,然后对这个对象进行一系列的处理。此外,可以通过调用实现具体函数的对象来解耦命令对象与接收对象。

正文

我们来通过车辆购买程序来展示这个模式,首先定义车辆购买的具体操作类:

$(function () {
    var CarManager = {
        // 请求信息

        requestInfo: function (model, id) {

            return 'The information for ' + model +

        ' with ID ' + id + ' is foobar';

        },
        // 购买汽车

        buyVehicle: function (model, id) {

            return 'You have successfully purchased Item '

        + id + ', a ' + model;

        },
        // 组织view

        arrangeViewing: function (model, id) {

            return 'You have successfully booked a viewing of '

        + model + ' ( ' + id + ' ) ';

        }

    };

})();

来看一下上述代码,通过调用函数来简单执行manager的命令,然而在一些情况下,我们并不想直接调用对象内部的方法。这样会增加对象与对象间的依赖。现在我们来扩展一下这个CarManager 使其能够接受任何来自包括model和car ID 的CarManager对象的处理请求。根据命令模式的定义,我们希望实现如下这种功能的调用:

CarManager.execute({ commandType: "buyVehicle", operand1: 'Ford Escort', operand2: '453543' });

根据这样的需求,我们可以这样啦实现CarManager.execute方法:
CarManager.execute = function (command) {

    return CarManager[command.request](command.model, command.carID);

};

改造以后,调用就简单多了,如下调用都可以实现(当然有些异常细节还是需要再完善一下的):
CarManager.execute({ request: "arrangeViewing", model: 'Ferrari', carID: '145523' });

CarManager.execute({ request: "requestInfo", model: 'Ford Mondeo', carID: '543434' });

CarManager.execute({ request: "requestInfo", model: 'Ford Escort', carID: '543434' });

CarManager.execute({ request: "buyVehicle", model: 'Ford Escort', carID: '543434' });

总结

命令模式比较容易设计一个命令队列,在需求的情况下比较容易将命令计入日志,并且允许接受请求的一方决定是否需要调用,而且可以实现对请求的撤销和重设,而且由于新增的具体类不影响其他的类,所以很容易实现。

但敏捷开发原则告诉我们,不要为代码添加基于猜测的、实际不需要的功能,如果不清楚一个系统是否需要命令模式,一般就不要着急去实现它,事实上,在需求的时通过重构实现这个模式并不困难,只有在真正需求如撤销、恢复操作等功能时,把原来的代码重构为命令模式才有意义。

Javascript 相关文章推荐
jQuery 研究心得 取得属性的值
Nov 30 Javascript
jquery 多行滚动代码(附详细解释)
Jun 17 Javascript
javascript中style.left和offsetLeft的用法说明
Mar 07 Javascript
基于jQuery+PHP+Mysql实现在线拍照和在线浏览照片
Sep 06 Javascript
全面解析Bootstrap中tab(选项卡)的使用方法
Jun 06 Javascript
js改变透明度实现轮播图的算法
Aug 24 Javascript
详解用函数式编程对JavaScript进行断舍离
Sep 18 Javascript
JS运动特效之同时运动实现方法分析
Jan 24 Javascript
JavaScript复制内容到剪贴板的两种常用方法
Feb 27 Javascript
JavaScript实现美化滑块效果
May 17 Javascript
js 闭包深入理解与实例分析
Mar 19 Javascript
基于vue实现简易打地鼠游戏
Aug 21 Javascript
深入理解JavaScript系列(33):设计模式之策略模式详解
Mar 03 #Javascript
JavaScript模拟重力状态下抛物运动的方法
Mar 03 #Javascript
深入理解JavaScript系列(31):设计模式之代理模式详解
Mar 03 #Javascript
深入理解JavaScript系列(30):设计模式之外观模式详解
Mar 03 #Javascript
深入理解JavaScript系列(29):设计模式之装饰者模式详解
Mar 03 #Javascript
jQuery对象与DOM对象之间的相互转换
Mar 03 #Javascript
深入理解JavaScript系列(28):设计模式之工厂模式详解
Mar 03 #Javascript
You might like
php比较两个字符串长度的方法
2015/07/13 PHP
PHP获取指定月份第一天和最后一天的方法
2015/07/18 PHP
如何让动态插入的javascript脚本代码跑起来。
2007/01/09 Javascript
XENON基于JSON变种
2010/07/27 Javascript
js类型检查实现代码
2010/10/29 Javascript
Javascript实现真实字符串剩余字数提示的实例代码
2013/10/22 Javascript
JQuery radio(单选按钮)操作方法汇总
2015/04/15 Javascript
深入探讨javascript函数式编程
2015/10/11 Javascript
nodejs微信公众号支付开发
2016/09/19 NodeJs
jQuery的deferred对象使用详解
2016/09/25 Javascript
BootStrap实现带关闭按钮功能
2017/02/15 Javascript
基于bootstrap实现多个下拉框同时搜索功能
2017/07/19 Javascript
js的各种数据类型判断的介绍
2019/01/19 Javascript
vue使用自定义指令实现拖拽
2021/01/29 Javascript
Python黑帽编程 3.4 跨越VLAN详解
2016/09/28 Python
python中执行shell的两种方法总结
2017/01/10 Python
django DRF图片路径问题的解决方法
2018/09/10 Python
python3.x实现base64加密和解密
2019/03/28 Python
Python3.6实现带有简单界面的有道翻译小程序
2019/04/16 Python
Python 中list ,set,dict的大规模查找效率对比详解
2019/10/11 Python
在Python中实现函数重载的示例代码
2019/12/12 Python
pytorch构建多模型实例
2020/01/15 Python
NumPy统计函数的实现方法
2020/01/21 Python
Python使用pickle进行序列化和反序列化的示例代码
2020/09/22 Python
python两个list[]相加的实现方法
2020/09/23 Python
Vans(范斯)德国官网:美国南加州的原创极限运动潮牌
2017/05/02 全球购物
struct和class的区别
2015/11/20 面试题
物业管理求职自荐信
2013/09/25 职场文书
给市场的环保建议书
2014/05/14 职场文书
廉政教育的心得体会
2014/09/01 职场文书
优秀教师事迹材料
2014/12/15 职场文书
2015年妇幼保健工作总结
2015/05/19 职场文书
《坐井观天》教学反思
2016/02/18 职场文书
党风廉政承诺书2016
2016/03/25 职场文书
MySQL时间设置注意事项的深入总结
2021/05/06 MySQL
解析高可用Redis服务架构分析与搭建方案
2021/06/20 Redis