什么是坏的系统设计

什么是好的系统设计?我不知道,但依我看,LaTeX 是坏的系统设计的一个典型,MFC 也如此,而坏的系统最重要的一个特点是,使用者不能把它作为一个黑匣子看待,而必须了解其内部构造才能有效使用它。

凡系统构造的时候,总希望隐藏内部的复杂性于简洁的接口背后,这样,用户只需要知道如何调用接口、这个接口实现了哪个功能就可以了,而不必了解其实现的细节。尽管 LaTeX 也是如此宣称的,可事实上并非如此,不了解实现细节,终究只能用到一些皮毛,稍微复杂一点的问题便解决不了。

举个例子,前些日子我希望实现这么一个功能,把每个章节标题的序号单独放在一列中,而正文与章节标题的文字对齐。如下:

1 Hello world..
A quick brown fox jumps over
a lazy dog.

按照默认的情况则是:

1 Hello world

A quick brown fox jumps over
a lazy dog.

可是,就算是实现书籍排版上这么常见的一个功能,LaTeX 也没有提供任何接口做到,不仅标准的文档类里面没有,连附加的宏包也没有实现这一功能的。所幸辗转所得一段代码能解决这个问题:

\makeatletter
\def\@seccntformat#1{\protect\makebox[0pt][r]{\csname
the#1\endcsname\quad}}
\makeatother

然而这段代码,根本是重新定义了 article 文档类中所用到标题数字格式,用到的纯属 TeX 的方法,和 LaTeX 简直毫无关系,试问若不看 article 的代码,怎能写出这段重定义的代码来,而这样一来,LaTeX 又怎么能算提供了一个黑匣子?

为什么说 LaTeX 对开发者来说也是糟糕的呢?是因为要写出这段代码来解决问题,首先你得对 LaTeX 的编程有所了解,否则 `\makeatletter`、`\makeatother` 是什么意思无从得知,第二得对纯 TeX 有了解,不然 `\def` 是什么意思也肯定不大了然,第三,你还得对别人写好的 article 文档类分析透彻,否则 `\csname` 是什么?`\@seccntformat` 又该放在哪里,有几个参数,从何得知?

这是 LaTeX 这种以编程的形式来排版的坏处,当然,也不能全归咎于形式,从 Knuth 始,大量的 LaTeX 开发人员,以及宏包的作者,都有一种把简单问题复杂化的倾向,好像不说得那么复杂无以显得自己水平多么高。明明一个参数就能解决问题的函数,非搞得七八个参数,看似灵活性高了,实则让人学起来、用起来头痛,没事谁愿意记你这个参数是干什么的?

最重要的是,这种方式不像 WYSWYG 的形式那么容易让人举一反三:同样一个功能,Adobe FrameMaker 中也没提供具体实现它的选项,但 FrameMaker 提供了几个很直观的功能:

首先,标题可以自动编号,你可以定制标题编号的格式
第二,可以创建一个在正文左侧的 column,成为 side-head,这一列保持空白,但标题可以跨越到这一列中
第三,标题编号的格式可以包含制表符

因此我自己就发现了可以用下述方法实现上边提到的功能:
首先,创建两个制表符:

     *    *

然后,把正文放在 side-head 右边的 column 里,标题则跨越到 side-head 中,但标题编号设置为 `\t\t` (`` 表示阿拉伯数字的编号,`\t` 表示一个制表符的宽度)。
接下来,只需要保证第二个制表符的位置,和 side-head 的右边界相同便可以实现我需要的功能了。

这让我想起 Web 标准推行中表格与 CSS 之争,表格该不该用于排版,现在倒是没什么好争的了,但大家却甚少考虑,为什么表格用于排版会会这么流行?W3C 可从来么鼓励过大家这么做,但为何只需要一人介绍,便应者云集?其实正是因为表格比 CSS 直观得多,表格一画,哪边居左,多少留右,上边高度多少,底部留多长,一目了然,设计者容易构思,而不像 CSS,还要考虑什么绝对宽度、相对宽度、固定位置,甚至还要用浮动之类的方法来扭扭捏捏的实现……

好的技术首先应该是易学的,否则纵然再好,也必然为公众所抛弃。

* 前面提到 MFC,这里权且补充两句,君不见《深入浅出 MFC》,《MFC Internals》之类的书卖得一直很好,倘若耍耍 AppWizard 便能精通 MFC,大家还用得着费那么大的劲,通过看 MFC 的代码来理解其深刻含义么?

说点感想

看汇编看得头痛,来写点感想,和大家交流交流。

我不知道看这个 blog 的朋友有多少是做程序的,或者是计算机专业的,可能设计师更多一些。然而我自己,一方面总还觉得自己多少能做点技术,另一方面又往往按耐不住设计一点东西的冲动。所以不妨在这里谈谈技术与艺术的一点点关系,我的理解。

首先是,千万不要把技术都当成特别高深的东西,是那些有外星人脑袋的理工科学生才能理解的。描述一个东西的简单,老外有句话,大意是你不需要是火箭工程师 (Rocket Scientist) 就能理解这个,估计他们能想到的最深奥的工程技术就是设计火箭吧。窃以为这种态度不对,好的技术首先应该是容易理解的技术,如果它不容易被人理解,首先便妨碍了自己被推广和被改进的可能性,一个不能不断改进的技术,又怎么能算顶尖的技术?50 年前大家用机器码编程,通过上下扳动开关和穿孔纸带来表示 0 和 1,其实首先妨碍的便是复杂系统的构建和验证,然后伟大的人出现了,我们有了汇编语言,终于可以用字符而不是数字来表达我们的想法了,可是汇编语言还是太像机器的思路了,每条语句都对应处理器的一个指令——这不是人思维的方式,同样妨碍了更复杂系统的构造,此后才出现高级语言,把我们从机器指令和复杂的内存管理中解放出来,专注于模块的分化,高层的抽象,使得灵活的系统构造成为可能。50 年前只有少数实验室的顶尖科学家才有机会触碰的东西,也就成为了现在人人都可以学,而且有很好的环境学的东西。所以我想,明智的技术应该是向着易于理解的方向发展的,不应该惧怕去理解它们。

第二,理解一个东西为何 (why) 这么设计是很有益的。在了解了 what 和 how 之后,why 不应该被忽略,而正是理解了 why,才能帮助你更好的理解更多的 what 和 how,事实上,真正给人的心智以启发,带有触类旁通效果的正是这个 why。现在计算机的软件环境发展得如此快,我们无法也没必要了解每一处的实现细节,但我想,和自己日常的工作关系最大的那部分细节一定要牢牢地掌握,一来自己就是靠这个吃饭的,二来了解了这个,你就不容易被种种花哨的宣传,官怪陆离的技术名词所迷惑,新技术、新概念、新提法天天都在出现,也天天都在过时,明智的人应当努力掌握一些不那么容易过时的东西。

第三,理解一门技术是应该付出一定代价的,如果谁告诉你这门技术又好又不需要花什么时间去学,那便应该谨慎从事。事实上,从我的观察来看,几乎没有一个高手是天生就有惊人的理解力和领悟力,在学习技术上,更现实一点的依靠是经验,而经验往往是从挫折中得到的。当我发现别人学习一门技术真的学得比我好,往往会发现他们比我更专注,比我有更多的兴趣,比我消耗了更多的脑细胞。此外,如果一定要说有什么捷径,那只能是在选择合适的文档上。

Web 方面的东西,有的时候会显得稍微好理解一些,做的人也容易浮躁一些,提出的种种新概念也要多一些,但相比起来也要短命一些,所以冷静的思考一下自己应该学点什么,把时间花在什么上,我想还是挺有必要的。

Web Developing Ideas

现在做的东西基本上和 Web 无关,所以也就很久找不到什么 Web 标准相关的东西,有的时候太注重效率了,做起东西来束手束脚的,也很不爽。

前一阵子我用 C 写过一个简单的模版库,用于高效率,但保留一定灵活性的 CGI 程序,不过这份代码已经和我的 C 盘一同被格掉了,所以现在可以放弃它,开始一些新的想法。

最近比较喜欢的几个东西有,用 PHP5 调用动态链接库 (.so) 文件的方式、在 PHP5 下使用 sqlite 轻量级数据库、用 lua 语言的一个扩展 CGILUA 写 CGI 程序、Perl 的 Template Toolkit,等等。时间紧张,来不及加上链接,有兴趣的可以自己 google 一下,不难找到,前两个 php.net 有文档,最后一个 O’Reilly 出了一本书。

IE and Standard support

不管是不是真的,现在这种中肯的陈述并不多见:IE Team 的 Chris Wilson 对 IE 关于标准的支持做的解释并非像我想象的那样充满废话。

作者还提醒了我们两点有趣的事实:

* IE 的 3, 4, 5 和 6 在发布的时候,都是对 CSS 支持最好的浏览器
* IE 有比其他任何一个浏览器大得多的向下兼容问题,因此也不得不对浏览器的“手术”慎之又慎

这些说法合情合理,但我仍觉得,不管说得多么好,还是得拿出一点实际的行动来,大家才会真正相信,目前 CSS 社群中 (对于 IE 要进行面向标准的改进) 的回应其实一直是很热情的。

Browser Speed Test

事实胜于雄辩,大家可以自己看看这个相当全面的浏览器速度测试,再比较一下我在上一篇 post 中对 Gecko 引擎速度的评价。

作者测试了 Linux、Mac 和 Windows 三个平台下几乎所有正在使用的主流浏览器,包括 Epiphany (Gecko), Firefox (Gecko), Konqeror, Mozilla 1.0 (Gecko), Mozilla 1.8 (Gecko), Opera 6, 7, 8 (beta), Camino (Gecko), iCab, OmniWeb, Safari, IE 5, IE 5/Mac (Tasman), IE 6 (Trident), K-Meleon (Gecko), Maxthon (Trident), Avant (Trident), Netscape 等浏览器在启动、CSS 渲染、表格渲染、脚本处理、图像载入等方面的速度,可以说是一个综合而全面的测试。

简单介绍一下大家主要关心的,Windows 平台下的情况:

* Opera 系列的最快,这个一点也不奇怪。
* 用 IE/Win 的 Trident 内核的速度都不错。
* Gecko 引擎是最慢的,早期的 Gecko 更是上不得台面。

Mozilla.org 上的广告词说得好:“Firefox 1.0 empowers you to browse faster.” Mozilla 则是 “an alternative to Microsoft IE and it’s faster to boot.” 现在看来,很有点讽刺的意味。