一次项目流产的小结
由于只得到一个模糊的答复,但我还是得先承认目前的状况:这个项目流产了,我是这个项目流产的最大关系人。
个人的各种问题和原因,我不多说,我现在只想说技术相关的。
这是来自 MySpace.cn/9911 的项目,做一个 Firefox 的插件,类似 Twitterfox,现在叫做 Echofon 的那个小东西。Firefox 的插件所使用的技术难度不大,JavaScript + XUL,再加点 CSS,很简单,打包成为 xpi 的时候可能还需要知道怎么用 bash,官方有一个自动打包的脚本,但有问题,需要自己修一修。一个对前端熟悉的开发者,再加点 Linux 平台下工作的经验,大致也有足够的基础开始开发了。
单元测试
我并非 quick and dirty 类型的开发者,如果我看代码的结构或者架构有点不爽了,我会小部分、甚至重构整个程序。对此,一个有效的 Unit Test 是最重要的保证。可惜,我没有写 Unit Test。JavaScript 有好些 Unit Test 框架,都是针对 Web 项目的,基于 HTML 的,并非 XUL 的。实际上,并没有一个用于单元测试的工具。当时我曾想过自己做一个简陋的,但终究没有做起来。基于浏览器的测试框架,大致可以通过 F5 刷新来完成测试,而基于 XUL 的,似乎只能通过手动点击更新 chrome 的按钮(通过开发辅助插件)。
我想过一个基于 Python 方案的方案, SpiderMonkey 有 Python 类库的实现。但是这充其量只能算是一个 JavaScript Parser,做语法检测还行,做单元测试是不足够的。
或者,会存在一个足够好的方案来达到自动化测试的目的,但我没有在项目初期做好一个完整的测试方案,若是想着做一个不断完善的东西,一个不断在重构中成长的软件(姑且算作是吧),没有完善的自动化测试方案,简直是笑话。达到工业级质量的软件,必须有单元测试作为后盾。
开发环境、版本控制和自动构建脚本
在项目初期,开发环境是 Windows XP,中途曾转换到 Ubuntu,也有短时间地在公司的 Mac 上进行开发(主要是界面的调整),但开发环境的不停变更,对项目开发,铁定是有影响的。先不说开发环境的配置需要大量的时间,光是一个小问题就足够烦恼了:自动构建脚本。
如果真的存在自动构建脚本,我想,率先需要测试的,肯定是这个东西。而且,这个东西还得能够自动侦测开发环境的不同而出现的差异,自动选择方案。bash shell 我一直觉得是一个很神奇很强大的东西,组合各个小工具写成的 script 可以很强大,可惜,这并不等于迁移到另一机器上就一定能够顺利运行。这也并非说这不好,至少,需要考虑自动构建脚本的健壮性问题。
至于版本控制,我认为我是弄得一塌糊涂的,一个像是在进行版本控制的开发过程;由于开发机的不固定,有点像是把 git 当作 svn 使用了。对于个人开发者来说,问题本是不大,但作为中央节点的机器硬盘出现了问题──中央节点的代码仓库坏了。当时最新的代码版本在某个开发机上,问题影响不大,但若真的需要版本回滚,或者其他──问题就出现了。这本是一个小问题,但要把 git 用得像 git,而非 svn ──这很重要,十分的重要。
类库
开始之时,XHR 和数据库的封装都是自己实现的。由于我固执地认为,需要把取回的消息本地存一份,所以我曾经有好几天的时间,用于钻研怎么在 Firefox 中用好 SQLite。问题是,在 Firefox 中,SQLite 是一个很奇怪的东西。对于并发的读,SQLite 没有问题。但是对于并发的写,例如多个进程或者线程,以异步的方式,在一个 IO 速度不稳定的设备(互联网)上取回数据,然后写入──这样,SQLite 很容易就会出现 deadlock。另一方面,SQLite API 的使用方法相对怪异(相对于习惯 PHP 所实现的 SQLite 封装的我来说)。虽然最近对于这个东西的开发中,我放弃了使用 SQLite 作为后端储存、甚至说没有储存除了帐号信息以后的数据,实际上也并不需要储存这些数据。
继续说类库。在中段有一些时候,不知道从哪里看到 jQuery 也可以在 XUL 的环境中使用,但实际上,需要修改很多很多的东西才能正常使用,如上文所属,没有单元测试保证,这样的改动就意味着人工测试,也意味着开发成本的增加、开发时间的增加。我勉强改了点,想着改名叫作 gQuery ── g stand for Gecko ── 但结果,也会随着现在这个东西的流产也流产了。
开发难度
可以说,开发这样的浏览器插件,是一个很有趣的挑战,现在回想起来就像跑进一个物种丰富的原始森林中觅食,你没有工具,虽然身边都是丰富的原材料。
先说界面。苏小雨的 CSS 2.1 手册是划时代的产品,这让我们知道了 CSS 2.1 有哪些属性,作用如何,但是整理这个出来也就是一个巨大的工程了。有这样的一个手册,我们可以知道哪个属性可以干点什么,作用是什么。再看看 developer.mozilla.org 上的这个页面:https://developer.mozilla.org/en/CSS_Reference
很不错,列出了很多。那么,试试把 -moz-appearance 找出来。Ctrl + F 是找不出来的,得找 Google,然后,你终于找到一个像样的说明了:https://developer.mozilla.org/en/CSS/-moz-appearance。
这足够吗?
Firefox 有一点不好:它能保证同样的 HTML 页面、同样的 CSS 代码在不同平台的 Firefox 下有一致的显示效果,却不能保证同样的 XUL + CSS 代码在不同平台的 Firefox 下有一致的显示效果。若非我所在的公司给我配了 Mac Mini 作为开发机,我怕是怎么也不知道,原来还得针对 Mac 的 Firefox 写 hack。对了,前面说的 -moz-appearance ── 这个属性得好好记住,跨平台的样式问题,首先考虑是不是它的问题就好了,摆弄 border、background 什么的,弄不懂按钮的样式,但加一句 -moz-appearance: none 以后,请随意折腾,像折腾 HTML 一样。
Firefox 在 Linux 下的效率被人诟病,我想着还有 XUL 的原因。scrollbox 是一个很不错的东西,试试鼠标按着 scrollbox 滚动条的下拉按钮不放,同期看看CPU占用率──无论在 Windows 还是 Ubuntu,在同一机器上,CPU 占用率都轻松突破 90%。或者看官的机器好一点,不会出现这么大的一个数字。
现在,我会认为这是一个开发难度很大的项目了。看看 zuosafox,对比它和 Twitterfox 的代码(我敢说 ZuosaFox 是抄袭和改动 TwitterFox 的源码做出来);细看 Twitterfox,他们的功能也不多,功能增加基本上停止了──请看源码架构,当然,没有好的测试工具怕也是原因之一。
小结
写了这么多,也不知道还有什么要写了──现已将近六月,这个项目由开始到现在,已经五个月了,我在其中所犯的错误太多,也不一一细数了。大致总结好了。
- 别把开发看得太简单。根据项目需求分析功能,然后调研。项目一上来就要求有这个那个的功能──稍等!先试试完成第一步,一个小小的功能,稳定了、符合了,重构,加功能,测试、重构。TDD 是一个良好的开发习惯。
- 即使增加一个小小的功能,对整个程序的架构也会有很大的影响。
- 良好的封装,完善的测试,是保持持续重构和优化的基础。
- 接上,工若善其事,必先礼其器,要甚至考虑,你所用的工具是否足够,例如单元测试框架,例如开发框架,例如文档和社区。
最后,我想着免不了对 9911 API 说点什么。这是一个有问题的 API,每个 URI,输出的同一个数据集、譬如说,user,都会存在问题,在 URI A 中,user 可能附带了字段 FOO,但在 URI B 的输出中,user 这个数据集就不包含 FOO 这个字段。他们大致没有好好地用 OO 来掩饰他们不良好的封装。试想一个只是写了一条 SQL 语句跑出结果、再扔 json_encode 中、最后把结果返回的脚本。封装不良好的一个问题就是,对测试不良好,但就我的感觉,我认为他们甚至没有单元测试。我希望我这两条推断都是错的。
May 25th 2010 • 10:05
by hlbice
进入 https://developer.mozilla.org/en/CSS_Reference 页面后,点击上面的 css 链接,进入 https://developer.mozilla.org/en/CSS ,下面有一个 view all…,点击进入 https://developer.mozilla.org/Special:Tags?tag=CSS&language=en ,就可以 Ctrl+F 查找到了。
May 26th 2010 • 04:05
by Leechael
Thanks! 忽略这个页面了。
Jun 14th 2010 • 10:06
by daqing
魔鬼隐藏于细节之中,所以如果对某个细节不熟悉,就会打乱自己的计划。