什么是坏的系统设计

什么是好的系统设计?我不知道,但依我看,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 方面的东西,有的时候会显得稍微好理解一些,做的人也容易浮躁一些,提出的种种新概念也要多一些,但相比起来也要短命一些,所以冷静的思考一下自己应该学点什么,把时间花在什么上,我想还是挺有必要的。

Comment Spam

现在每次上来就是狂删一通 Comment Spam,这也不是个办法啊。

WordPress 这么久没有发布新的版本,以至于缺乏官方的对抗 Comment Spam 的办法,各种 plugins、hacks 泛滥,但往往治标不治本,从一个侧面上说,这也助长了 Comment Spam 的肆虐。看起来还是 MT 做得好些

顺便说说,XMLHttpRequest 其实是一个很有趣东西,可以在不刷新页面的情况下,让浏览器通过 JavaScript 在页面背后提交数据和接受处理结果,这在一些应用中很方便,有空可以看看,说不定能派上用场。

About Wiki

更新:谢谢 murj 提供的资料,现在 Dokuwiki 确实是一个比较好的选择,但是目前要架设起来还有一些工作要做:

1. 需要一份本地化版本,这个我正在做;
2. 需要一个简洁的名称,这个恐怕费些思量,欢迎大家提供;
3. 需要一个稳定的域名 (最好和 Web 有一定关系),如果您可以把域名指向到 211.100.8.117,我可以让这里的管理员把来自该域名的访问指向到 http://opencjk.org/~jjgod/wiki 目录;
4. 需要对原来 Dokuwiki 的样式表作一定修改,这方面我实在不擅长,如果有朋友愿意帮忙的话,可以把修改过的 stylesheet 上传到自己可以访问的地方,然后和我联系,我会把程序中原来指向 style.css 的位置改为您指定的位置;
5. 需要对 Wiki 的目录作一个比较合理的规划组织,这个如果照着 CSS-Discuss wiki 来做,应该并不困难,问题是我现在上网时间有限,可能会慢一点,欢迎大家一起来完成。

谢谢支持。