源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

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

  • 时间:2020-02-15 07:01 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:JavaScript 组件之旅(一)分析和设计
另一方面,由于 JavaScript 通常会和宿主环境(比如浏览器)紧密结合,因此缺乏功能强大而简单易用的开发工具。在这样的环境中,开发组件或框架成为一项具有挑战的工作。 这次,我们将以一个简易的 JavaScript 组件开发为契机,逐步展开组件的分析、设计、实现、构建和测试等任务,探讨组件开发过程涉及的方方面面。这些探讨将分 4 篇陆续张贴出来(链接将在张贴后更新): [list=1] [*][b]分析和设计组件[/b] [/*][*]编码实现和算法 [/*][*]用 Ant 构建组件 [/*][*]测试 JavaScript 组件 [/*][/list] 现在,假设我们要从头开始设计并实现一个[b]队列管理组件[/b],先让我们来认识一下队列:
[img]http://files.jb51.net/upload/20091028144544496.png[/img] Queue
图片来自 Wikipedia. 队列是一个“先进先出”(FIFO) 的数据结构,只能向它的尾巴追加项,项从头部取出使用,这个规则将应用到我们所探讨的组件中去。对于队列,相信学过 C 或是数据结构课程的同学已有所了解,如果你已经把它还给了老师,请使用搜索引擎简单了解一下队列的知识。 这个队列管理组件具体要实现的功能是:它是个任务管理器,按高、中、低优先级维护着三个任务队列,客户(使用者)可以在任何时候把想要执行的任务添加到某个队列,可以指定任务运行的上下文,并传给它必要的数据。客户也可以随时运行这个队列,队列里的任务按照指定的依赖关系以合理的方式依次运行。 为了不至于使组件过于简单而缺乏实用性,我们特意给它添加了一些“糖”:分优先级、传入上下文和数据、处理依赖关系。如果把上面这段理解为需求的话,那么首先,我们要从中提取出最重要的关键词,它们直接决定了这个组件应该如何设计: [list] [*]队列 [/*][*]优先级 [/*][*]依赖关系 [/*][/list] 然后,我们从中提炼出涉及的对象: [list] [*][b]任务管理器 (TaskManager)[/b]: 从目前需求来看,它只需要一个实例。 [/*][*][b]队列 (Queue)[/b]: 每个优先级对应一个队列,由 [code]TaskManager[/code] 管理这三个 [code]Queue[/code] 实例。 [/*][*][b]任务 (Task)[/b]: 描述添加的任务,放在相应优先级的 [code]Queue[/code] 里面。 [/*][*][b]依赖 (Dependency)[/b]: 描述单一的依赖,即 [code]Task1[/code] 依赖 [code]Task2[/code], 显然某个 [code]Task[/code] 可能具有多个依赖。 [/*][/list] 它的对象模型可以大概表示如下:
[img]http://files.jb51.net/upload/20091028144544758.png[/img] 设计初期的对象图
注意到 [code]Dependency[/code] 实际上并没有做什么事,而 [code]Queue[/code] 的两个方法可以分别交给 [code]TaskManager[/code] & [code]Task[/code] 来负责。一个方法到底由哪个对象负责,是很容易引起争论的话题,不在我们的讨论范围内。这次,我们的重点是,采用 JavaScript 实现这个组件,结合 JavaScript 独特的语言特性,我们设想实现上述四个对象: [list] [*][code]TaskManager[/code] 直接通过对象 (Object) 实现。在 JavaScript 的世界,对象可以作为天然的静态类来使用——你可以直接在“类” [code]ClassObject[/code] 里面定义属性方法 [code]property[/code],并以静态类的方式来引用 [code]CassObject.property[/code]. [/*][*][code]Queue[/code] 以数组 (Array) 的形式体现出来,[code]Task[/code] 则是数组中存放的每一项。对 [code]Queue[/code] 进行操作必然要在其 prototype 中定义一些实例方法,由于每个 Queue 实例都是原生的数组,为了减少对 [code]Array.prototype[/code] 的侵入,我们可以考虑将这些方法定义到 [code]Task.prototype[/code] 上——将职责转移到任务上。 将三个 [code]Queue[/code] 数组集结在一起,形成一个“大数组”以表示三个不同优先级的队列,这个大数组可以作为 [code]TaskManager[/code] 的属性。 [/*][*]任务的核心是一个 function, 本来可以直接用 function 来表示一个任务,但考虑到它具有自身独特的属性(优先级、依赖等等),而且是最经常被操作的对象,以后可能还会进行扩展,所以我们决定单独将其定义成对象。 [/*][*]依赖直接以数组的形式作为 [code]Task[/code] 的一个属性存在——[code]Task[/code] 将依赖的其他多个 [code]Task[/code] 标识符放在这个数组中,不再单独定义这个对象。 [/*][/list] 分析下来,局势逐渐明朗——我们需要将四个对象简化成两个:[b][code]TaskManager[/code][/b] &[b][code]Task[/code][/b], 另外两个对象用原生的数组来实现:
[img]http://files.jb51.net/upload/20091028144544447.png[/img] 简化后的对象模型
又注意到这里多次以数组来实现,而编码过程中必然涉及到数组的遍历、查找等操作,JavaScript 1.6 已经为我们实现了这些数组操作。为了充分利用数组内置的原生方法,又能在较老的浏览器中运行,我们使用了 Eric 的代码。这样,我们可以直接使用诸如 [code]forEach[/code]/[code]indexOf[/code] 等方法,更关注组件的功能实现,而且在现代浏览器中获得较好的性能。 ~~~~~~~~~~~~~ 八卦分割线 ~~~~~~~~~~~~~ 嗯,在严肃地分析了组件设计之后,就要踏上快乐的编码实现之旅了。别急,[code]TaskManager[/code] 似乎俗气了一点:不足以表达具有优先级、依赖管理的任务队列,而且用它做命名空间有跟其他代码冲突的可能性。好吧,这个组件就叫[b][code]Smart Queue[/code][/b] 吧,响亮而又独特.^^ 分析设计好了,名字也有了,欲知具体实现过程,且听下回分解。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部