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 相关文章推荐
让浏览器DOM元素最后加载的js方法
Jul 29 Javascript
IE中getElementsByName()对有些元素无效的解决方案
Sep 28 Javascript
js实现最短的XML格式化工具实例
Mar 12 Javascript
js和jquery分别验证单选框、复选框、下拉框
Dec 17 Javascript
微信小程序 石头剪刀布实例代码
Jan 04 Javascript
详谈for循环里面的break和continue语句
Jul 20 Javascript
jQuery Easyui Treegrid实现显示checkbox功能
Aug 08 jQuery
详解ES6 Promise对象then方法链式调用
Oct 20 Javascript
微信小程序自定义单项选择器样式
Jul 25 Javascript
layui动态渲染生成select的option值方法
Sep 23 Javascript
你知道JavaScript Symbol类型怎么用吗
Jan 08 Javascript
vue实现带过渡效果的下拉菜单功能
Feb 19 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
windows xp下安装pear
2006/12/02 PHP
php通过COM类调用组件的实现代码
2012/01/11 PHP
PHP页面间参数传递的四种方法详解
2013/06/09 PHP
Codeigniter上传图片出现“You did not select a file to upload”错误解决办法
2014/06/12 PHP
PHP5.3新特性小结
2016/02/14 PHP
PHP反射API示例分享
2016/10/08 PHP
php简单计算年龄的方法(周岁与虚岁)
2016/12/06 PHP
基于prototype的validation.js发布2.3.4新版本,让你彻底脱离表单验证的烦恼
2006/12/06 Javascript
JS的replace方法详细介绍
2012/11/09 Javascript
jquery实现手风琴效果实例代码
2013/11/15 Javascript
php,js,css字符串截取的办法集锦
2014/09/26 Javascript
Javascript aop(面向切面编程)之around(环绕)分析
2015/05/01 Javascript
JavaScript提高网站性能优化的建议(二)
2016/07/24 Javascript
微信小程序学习(4)-系统配置app.json详解
2017/01/12 Javascript
JS排序之选择排序详解
2017/04/08 Javascript
利用js给datalist或select动态添加option选项的方法
2018/01/25 Javascript
Vue2.0仿饿了么webapp单页面应用详细步骤
2018/07/08 Javascript
使用webpack打包后的vue项目如何正确运行(express)
2018/10/26 Javascript
vue3.0实现点击切换验证码(组件)及校验
2020/11/18 Vue.js
简单谈谈Python流程控制语句
2016/12/04 Python
python+pillow绘制矩阵盖尔圆简单实例
2018/01/16 Python
python3+PyQt5 创建多线程网络应用-TCP客户端和TCP服务器实例
2019/06/17 Python
python循环嵌套的多种使用方法解析
2019/11/29 Python
Python如何把多个PDF文件合并代码实例
2020/02/13 Python
python使用docx模块读写docx文件的方法与docx模块常用方法详解
2020/02/17 Python
python实现交并比IOU教程
2020/04/16 Python
Python如何实现远程方法调用
2020/08/07 Python
matplotlib绘制鼠标的十字光标的实现(自定义方式,官方实例)
2021/01/10 Python
简单掌握CSS3将文字描边及填充文字颜色的方法
2016/03/07 HTML / CSS
浅谈css3新单位vw、vh、vmin、vmax的使用详解
2017/12/01 HTML / CSS
大二法英学生职业生涯规划范文
2014/02/27 职场文书
竞选班干部演讲稿300字
2014/08/20 职场文书
农村党支部书记司法四风问题对照检查材料
2014/09/26 职场文书
新郎新娘致辞
2015/07/31 职场文书
ConstraintValidator类如何实现自定义注解校验前端传参
2021/06/18 Java/Android
nginx日志格式分析和修改
2022/04/28 Servers