网络编程
位置:首页>> 网络编程>> JavaScript>> JavaScript 组件之旅(一):分析和设计

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

作者:太伯 来源:Alipay UED 发布时间:2009-09-21 10:52:00 

标签:组件,JavaScript,设计

毫无疑问,JavaScript 是一种非常灵活的脚本语言,有时候它像一只难以驯服的野马——你受益于它的灵活性的同时,也要时刻提防它变得失去控制;另一方面,由于 JavaScript 通常会和宿主环境(比如浏览器)紧密结合,因此缺乏功能强大而简单易用的开发工具。在这样的环境中,开发组件或框架成为一项具有挑战的工作。

这次,我们将以一个简易的 JavaScript 组件开发为契机,逐步展开组件的分析、设计、实现、构建和测试等任务,探讨组件开发过程涉及的方方面面。这些探讨将分 4 篇陆续张贴出来(链接将在张贴后更新):

  1. 分析和设计组件

  2. 编码实现和算法

  3. 用 Ant 构建组件

  4. 测试 JavaScript 组件

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


Queue

图片来自 Wikipedia.

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

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

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

  • 队列

  • 优先级

  • 依赖关系

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

  • 任务管理器 (TaskManager): 从目前需求来看,它只需要一个实例。

  • 队列 (Queue): 每个优先级对应一个队列,由 TaskManager 管理这三个 Queue 实例。

  • 任务 (Task): 描述添加的任务,放在相应优先级的 Queue 里面。

  • 依赖 (Dependency): 描述单一的依赖,即 Task1 依赖 Task2, 显然某个 Task 可能具有多个依赖。

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

设计初期的对象图

注意到 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 1.6 已经为我们实现了这些数组操作。为了充分利用数组内置的原生方法,又能在较老的浏览器中运行,我们使用了 Eric 的代码。这样,我们可以直接使用诸如 forEach/indexOf 等方法,更关注组件的功能实现,而且在现代浏览器中获得较好的性能。

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

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

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

0
投稿

猜你喜欢

  • Cookies,有些人喜欢它们,有些人憎恨它们。但是,很少有人真正知道如何使用它们。现在你可以成为少数人中的成员-可以自傲的Cookie 大
  • List:1. 什么叫商品评论?2. 评论体系的存在意义3. 评论体系的现状4. 都有哪些元素5. 该如何设计?6. 评论体系之外1.什么叫
  • 有一编文章是用JavaScript对XML文件操作来实现无限级联动菜单的,我们可结合ASP来完成对数据库值的读取,然后写入XML文件,再用J
  • 迄今为止,导出/导入工具集仍是跨多个平台转移数据所需劳动强度最小的首选实用工具,尽管人们常常抱怨它速度太慢。导入只是将每条记录从导出转储文件
  • 下面这段代码是兼容IE的图片切换代码,请问各位老鸟如何兼容FF,或者有相类似无按钮无数字兼容FF的图片切换代码?<!DOCTYPE h
  • 这个翻滚代码没有使用什么marquee或者其它位移方法,而是每隔一秒把列表最顶端的那个li删掉,把这个li里面的内容插入到最底端新生成的li
  • 昨天在网上看到一个防采集软件,说采集只访问当前网页,不会访问网页的图片、JS等,今天突然想到,通过动态程序和Js访问分别记录访问者的IP,然
  • 我们可用下面的代码将服务器端变量转换为客户端的JavaScrit变量:<%@ Language=VBScript 
  • 看起来现在经常用到这样的效果来提高用户体验,所以就没事写了一个输入框提示列表的效果使用宽屏的朋友麻烦帮忙测试下,列表的位置有没有错位。代码可
  • Jabob Nielsen提出的10个可用性原则中有一个原则-防止出错(Error Prevention)。官网中有对这一原则的具体解释,这
  • 今天想说的是内容和容器的关系,顺便把之前设计中碰到的问题和大家一起探讨下。我们从软件的设置说起。(这里以QQ的设置举例)一个软件的设置(常称
  • language.xml 代码如下:<?xml version="1.0" encoding=
  • 设置密码保护SqlServer数据库备份文件! 备份SqlServer数据库 Backup Database [数据库] To disk=&
  • BluePrint是一个非常成熟也非常流行的CSS框架,很多网站和wordpress基于Blueprint搭建前端结构。最近,bluepri
  • 在学习asp过程中相信很多初学者对Sub与Function的用法有些疑惑,好像它们没什么区别都可以使用。呵呵,看了本文的介绍您就可以了解了S
  • 在设计网页之前,客户或产品经理会提出对网页视觉风格设计的期望:活跃、大气、稳重、信赖、都市化….. 设计师一听到关键词或许很自然地在心里蹦出
  • 1. ORACLE 的解析器按照从右到左的顺序处理 FROM 子句中的表名,因此 FROM 子句中写在最后的表(基础表 driving ta
  •     最近一个项目中遇到ASP对FoxPro库表(*.DBF)的操作问题。现实中确有许多应用软件使
  • 本文介绍如何利用带进度条的ASP无组件实现断点续传下载大文件。<%@LANGUAGE="VBSCRIPT"&nbs
  • 缓存是基于Application实现的CacheState类,建议实例化时用名Cache程序代码<% Class Cache
手机版 网络编程 asp之家 www.aspxhome.com