JavaScript 组件之旅(一)分析和设计


Posted in Javascript onOctober 28, 2009

另一方面,由于 JavaScript 通常会和宿主环境(比如浏览器)紧密结合,因此缺乏功能强大而简单易用的开发工具。在这样的环境中,开发组件或框架成为一项具有挑战的工作。
这次,我们将以一个简易的 JavaScript 组件开发为契机,逐步展开组件的分析、设计、实现、构建和测试等任务,探讨组件开发过程涉及的方方面面。这些探讨将分 4 篇陆续张贴出来(链接将在张贴后更新):

  1. 分析和设计组件
  2. 编码实现和算法
  3. 用 Ant 构建组件
  4. 测试 JavaScript 组件

现在,假设我们要从头开始设计并实现一个队列管理组件,先让我们来认识一下队列:

JavaScript 组件之旅(一)分析和设计

Queue

图片来自 Wikipedia.

队列是一个“先进先出”(FIFO) 的数据结构,只能向它的尾巴追加项,项从头部取出使用,这个规则将应用到我们所探讨的组件中去。对于队列,相信学过 C 或是数据结构课程的同学已有所了解,如果你已经把它还给了老师,请使用搜索引擎简单了解一下队列的知识。

这个队列管理组件具体要实现的功能是:它是个任务管理器,按高、中、低优先级维护着三个任务队列,客户(使用者)可以在任何时候把想要执行的任务添加到某个队列,可以指定任务运行的上下文,并传给它必要的数据。客户也可以随时运行这个队列,队列里的任务按照指定的依赖关系以合理的方式依次运行。

为了不至于使组件过于简单而缺乏实用性,我们特意给它添加了一些“糖”:分优先级、传入上下文和数据、处理依赖关系。如果把上面这段理解为需求的话,那么首先,我们要从中提取出最重要的关键词,它们直接决定了这个组件应该如何设计:

  • 队列
  • 优先级
  • 依赖关系

然后,我们从中提炼出涉及的对象:

  • 任务管理器 (TaskManager): 从目前需求来看,它只需要一个实例。
  • 队列 (Queue): 每个优先级对应一个队列,由 TaskManager 管理这三个 Queue 实例。
  • 任务 (Task): 描述添加的任务,放在相应优先级的 Queue 里面。
  • 依赖 (Dependency): 描述单一的依赖,即 Task1 依赖 Task2, 显然某个 Task 可能具有多个依赖。

它的对象模型可以大概表示如下:

JavaScript 组件之旅(一)分析和设计

设计初期的对象图

注意到 Dependency 实际上并没有做什么事,而 Queue 的两个方法可以分别交给 TaskManager & Task 来负责。一个方法到底由哪个对象负责,是很容易引起争论的话题,不在我们的讨论范围内。这次,我们的重点是,采用 JavaScript 实现这个组件,结合 JavaScript 独特的语言特性,我们设想实现上述四个对象:

  • TaskManager 直接通过对象 (Object) 实现。在 JavaScript 的世界,对象可以作为天然的静态类来使用——你可以直接在“类” ClassObject 里面定义属性方法 property,并以静态类的方式来引用 CassObject.property.
  • Queue 以数组 (Array) 的形式体现出来,Task 则是数组中存放的每一项。对 Queue 进行操作必然要在其 prototype 中定义一些实例方法,由于每个 Queue 实例都是原生的数组,为了减少对 Array.prototype 的侵入,我们可以考虑将这些方法定义到 Task.prototype 上——将职责转移到任务上。
    将三个 Queue 数组集结在一起,形成一个“大数组”以表示三个不同优先级的队列,这个大数组可以作为 TaskManager 的属性。
  • 任务的核心是一个 function, 本来可以直接用 function 来表示一个任务,但考虑到它具有自身独特的属性(优先级、依赖等等),而且是最经常被操作的对象,以后可能还会进行扩展,所以我们决定单独将其定义成对象。
  • 依赖直接以数组的形式作为 Task 的一个属性存在——Task 将依赖的其他多个 Task 标识符放在这个数组中,不再单独定义这个对象。

分析下来,局势逐渐明朗——我们需要将四个对象简化成两个:TaskManager & Task, 另外两个对象用原生的数组来实现:

JavaScript 组件之旅(一)分析和设计

简化后的对象模型

又注意到这里多次以数组来实现,而编码过程中必然涉及到数组的遍历、查找等操作,JavaScript 1.6 已经为我们实现了这些数组操作。为了充分利用数组内置的原生方法,又能在较老的浏览器中运行,我们使用了 Eric 的代码。这样,我们可以直接使用诸如 forEach/indexOf 等方法,更关注组件的功能实现,而且在现代浏览器中获得较好的性能。

~~~~~~~~~~~~~ 八卦分割线 ~~~~~~~~~~~~~

嗯,在严肃地分析了组件设计之后,就要踏上快乐的编码实现之旅了。别急,TaskManager 似乎俗气了一点:不足以表达具有优先级、依赖管理的任务队列,而且用它做命名空间有跟其他代码冲突的可能性。好吧,这个组件就叫 Smart Queue 吧,响亮而又独特.^^

分析设计好了,名字也有了,欲知具体实现过程,且听下回分解。

Javascript 相关文章推荐
js借助ActiveXObject实现创建文件
Sep 29 Javascript
JS操作数据库的实例代码
Oct 17 Javascript
jquery实现炫酷的叠加层自动切换特效
Feb 01 Javascript
Shell脚本实现Linux系统和进程资源监控
Mar 05 Javascript
JQuery替换DOM节点的方法
Jun 11 Javascript
Validform+layer实现漂亮的表单验证特效
Jan 17 Javascript
关于Iframe父页面与子页面之间的相互调用
Nov 22 Javascript
javascript实现去除HTML标签的方法
Dec 26 Javascript
jQuery实现动画、消失、显现、渐出、渐入效果示例
Sep 06 jQuery
详解html-webpack-plugin插件(用法总结)
Sep 12 Javascript
Vue2 添加数据可视化支持的方法步骤
Jan 02 Javascript
JavaScript实现Tab标签页切换的最简便方式(4种)
Jun 28 Javascript
js 数组实现一个类似ruby的迭代器
Oct 27 #Javascript
jquery 操作单选框,复选框,下拉列表实现代码
Oct 27 #Javascript
javascript获得CheckBoxList选中的数量
Oct 27 #Javascript
基于jQuery的日期选择控件
html 锁定页面(js遮罩层弹出div效果)
Oct 27 #Javascript
javascript 读取XML数据,在页面中展现、编辑、保存的实现
Oct 27 #Javascript
Ajax+Json 级联菜单实现代码
Oct 27 #Javascript
You might like
提升PHP执行速度全攻略
2006/10/09 PHP
对javascript和select部件的结合运用
2006/10/09 PHP
PHP 反射机制实现动态代理的代码
2008/10/22 PHP
实战mysql导出中文乱码及phpmyadmin导入中文乱码的解决方法
2010/06/11 PHP
php利用iframe实现无刷新文件上传功能的代码
2011/09/29 PHP
php根据年月获取当月天数及日期数组的方法
2016/11/30 PHP
PHP实现生成模糊图片的方法示例
2017/12/21 PHP
Laravel框架Request、Response及Session操作示例
2019/05/06 PHP
PHPStorm2020.1永久激活及下载更新至2020(推荐)
2020/09/25 PHP
关于JavaScript的with 语句的使用方法
2011/05/09 Javascript
从数据结构的角度分析 for each in 比 for in 快的多
2013/07/07 Javascript
jquery+css3实现会动的小圆圈效果
2016/01/27 Javascript
基于JavaScript的操作系统你听说过吗?
2016/01/28 Javascript
AngularJS深入探讨scope,继承结构,事件系统和生命周期
2016/11/02 Javascript
将JSON字符串转换成Map对象的方法
2016/11/30 Javascript
bootstrap table插件的分页与checkbox使用详解
2017/07/23 Javascript
在Layui 的表格模板中,实现layer父页面和子页面传值交互的方法
2019/09/10 Javascript
小程序使用watch监听数据变化的方法详解
2019/09/20 Javascript
vue仿淘宝滑动验证码功能(样式模仿)
2019/12/10 Javascript
vue中渲染对象中属性时显示未定义的解决
2020/07/31 Javascript
antd 表格列宽自适应方法以及错误处理操作
2020/10/27 Javascript
基于Cesium绘制抛物弧线
2020/11/18 Javascript
pycharm远程调试openstack的图文教程
2017/11/21 Python
python 读取DICOM头文件的实例
2018/05/07 Python
基于scrapy的redis安装和配置方法
2018/06/13 Python
python 用下标截取字符串的实例
2018/12/25 Python
Python 实现二叉查找树的示例代码
2020/12/21 Python
HTML5视频播放插件 video.js介绍
2018/09/29 HTML / CSS
EJB包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的?
2013/02/17 面试题
应届电子商务毕业自荐书范文
2014/02/11 职场文书
服务承诺书范文
2014/05/19 职场文书
财务工作疏忽检讨书
2014/09/11 职场文书
2014年小学教研工作总结
2014/12/06 职场文书
2015年共青团工作总结
2015/05/15 职场文书
优秀教师工作总结2015
2015/07/22 职场文书
python+opencv实现视频抽帧示例代码
2021/06/11 Python