2008年12月31日星期三

我的2008

上半年:专业学习,
参与了导师的一个科研项目,有些结果,感觉很烂,倒也学到不少东西。
暑假:hp培训,华迪实习,
下半年:税务局项目,很累,常常加班到夜里3、4点,通宵
也算一段磨练,还有点收入。
平均每周上2节课,要点名,考前花两小时看下书
签了工作,一个变态公司,挑战。

偶尔玩下游戏,放松

多事的2008,也对这个现实的世界有了另一番认识。
认识了一些朋友,缘分。

这一年倒也充实

想找个没电脑、汽车、噪声的地方睡觉,看书……
回家
那里有明媚的阳光,新鲜的空气,
微风,鸟叫,河流,原野,宁静……

很多年没享受家乡的春天了,
想必以后也没什么机会了。
怀念

2008年11月29日星期六

冰川下的秘密

你知道冰川的90%出自水下这样一个事实吗?使得,大多数软件也是这样——用户接口设计只占到大约10%的工作量,而90%的编程工作都不是浮现在表面可以看得见的。再说,要是将修复故障所花的时间按也计算在内的话,那么用户界面方面的工作量就只占到整个工作量的5%了。更进一步地说,加入只是把眼睛放在用户界面的可视部分上面,那么所花的时间连1%就不到。

推论1. 如果你把一个程序的90%的用户界面设计的很差劲拿给某位非程序人员看,那么他会认为整个程序的90%都是糟糕的。
推论2. 要是你让非程序人员看一个精美的没法挑剔的用户界面,那么他们就会认为该程序基本上是搞定了。

推论3. 当你在向人推介自己的作品时,唯一要紧的事情就是让人对屏幕感觉良好,百分之百地要让它做得好看。

确保要事实本身而不是人们的任何看法来评估项目是否在以正常的速度向前推进。

——Joel on Software

ps:《Joel on software》中文版翻译的实在是烂

2008年10月1日星期三

技术法则

当所有的努力都失败后,就看看手册吧。——墨菲技术法则

任何非常先进的技术简直就是魔术。——墨菲技术法则

如果花时间任何事情都会成功,如果花足够长的时间就会超越它。——墨菲技术法则

“更换一个电灯泡需要多少软件工程师?”
“不需要。在手册中已经说明。”
“不需要。这是硬件问题。”
“一个。但是他到2010年才能完成。”
“两个。而且其中一个必定在项目过程中离开。”
“四个。一个负责设计更换,一个负责执行,一个负责编写文档,最后一个负责今后的维护。”

一个不能正常运行的复制系统总是从一个运作良好的简单系统演化而来的。——墨菲技术法则

专家就是对越来越窄的领域知道得越来越多,最终对该领域完全了然于胸的人。——墨菲技术法则

逻辑往往是一种自信地导致错误结论的系统方法。——墨菲技术法则

任何简单的思想都将用最复杂的方式表述。——墨菲技术法则

在周五下午4:30以后,任何bug都得不到及时修复。但在周一早上9:15正确的解决方案就不言自明了。——墨菲第五推论

除了终端用户以外谁也不能检测到软件的bug。——墨菲技术法则

如果建筑工人想程序员编写程序那样建造大楼,那么来的第一个啄木鸟也许就会毁灭文明。——墨菲技术法则

只需要看就可以观察到很多。——贝拉的第一法则

当事情进展顺利时,没有人注意到!——齐默曼的抱怨法则

没有障碍的路可能哪里也到不了。——狄弗克

没有任何事物简单到不会被误解。——傅雷曼法则

每个解决方案都会带来新问题。——墨菲第五推论

每个人都有一个还没有实施的计划。——豪的法则

墨菲是一个乐天派。——贝克的假设条件

2008年8月7日星期四

PC历史上的20位英雄

PC历史上的20位英雄
webzen发布于 2008-08-07 20:29:37
回首PC的20年,它的历史就是一部英雄的历史,一个个闪亮的名字,就像一颗颗璀璨的星星,为人羡慕、令人敬仰;他们对PC业的兴起,对计算机技术的繁荣,对人类的贡献是我们不应忘记的。当本文重现历史的一幕幕时,我们会看到什么?无疑,其中有光辉与荣耀,有财富与成就,当然,也有遗憾与悲怆……

一、电脑始祖冯·诺依曼

 

冯·诺依曼(John Von Neuman)凭他的天才和敏锐,在电脑初创期,高屋建瓴地提出了现代计算机的理论基础,从而规范和决定了电脑的发展方向。时至今日,我们所有的电脑又都叫“冯·诺依曼机器”,就是对这位数学天才最好的评价。

对于冯·诺依曼来说,人类第一台电脑造了一半时才参与开发,多少有些遗憾。但是,他刚好在那大机器程序存储问题无法解决的关键时刻出现,这使得冯·诺依曼的天才得到淋漓尽致的发挥。他明确指出:一定要彻底实现程序由外存储向内存储的转化,原有的设计必须作修改,经费不够再追加。在冯·诺依曼的影响下,整个研制工作取得了突破性的进展。冯·诺依曼提出了新的改进方案:一是用二进制代替十进制,进一步提高电子元件的运算速度;二是存储程序(Stored Program),即把程序放在计算机内部的存储器中,换言之,把能进行数据处理的程序放在数据处理系统内部,程序和该程序处理的数据用同样的方式储存,即把程序本身当作数据来对待。冯·诺依曼的改进方案被称为“爱达法克”(EDVAC),即离散变量自动电子计算机(Electronic Diserete Variable Computer)的简称。

1945年6月,他写了一篇题为《关于离散变量自动电子计算机的草案》的论文,第一次提出了在数字计算机内部的存储器中存放程序的概念(Stored Program Concept),这是所有现代电子计算机的范式,被称为“冯·诺依曼结构”。按这一结构建造的电脑称为存储程序计算机(Stored Program Computer),又称为通用计算机。时至今日,所有的电脑都逃脱不了冯·诺依曼的掌心,我们所有的电脑,都有一个共同的名字,叫“冯·诺依曼机器”,它超越了品牌、国界、速度和岁月。

二、摩尔定律:高登·摩尔

当人们不断追逐新款PC时,殊不知这后面有一只无形的大手在推动,那就是摩尔定律,而这著名定律的发明人就是高登·摩尔(Gordon Moore)。

1965年的一天,摩尔顺手拿了把尺子和一张纸,画了一张草图,纵坐标代表不断发展的集成电路,横坐标是时间。他在月份上逐个描点,得到一幅增长的曲线图。这条曲线显示出每24个月,集成电路由于内部晶体管数量的几何级数的增长,而使性能几乎翻倍提高,同时集成电路的价格也恰好减少一倍。后来高登·摩尔把时间调整为18个月。摩尔是在集成电路技术的早期作出结论的,那时候,超大规模集成电路技术还远未出现,所以他在1965年的预言并未引起世人的注意。

高登·摩尔的另一壮举是在1968年与罗伯特·诺伊斯带头“造反”,率领一群工程师离开仙童公司,成立了一家叫集成电子的公司,简称“Intel”,这就是今日名震世界的英特尔公司。

三、预言大师:阿伦·凯

凯的形象既不像傲慢自大、反潮流的黑客,也不同于一夜暴富的计算机富翁,更不像象牙塔里的计算机科学家。他时常穿着跑鞋和灯芯绒裤子,一小撮胡子,短短的、略微零乱的头发,使他看上去极为普通。即使他是你的老板,可能也不会给你留下多深的印象。但这也不是说他很谦逊,他喜欢引用自己的话,且经常以这样的词作为发言的开端:“凯的第一法则指出……”。

阿伦·凯(Alan Kay)不是一位公众人物,但在计算机界,尤其是技术圈内,他是能让大家都心服口服屈指可数的大师之一。成为硅谷的又一位亿万富翁或让他当麻省理工的院长,都无法激起他的兴奋,但他会有足够的耐性与一群8岁左右的孩子一起玩电脑。他最大的乐趣就是发明他喜欢的东西。

阿伦·凯是Smalltalk面向对象编程环境语言的发明人之一,也是面向对象编程思想的创始人之一,同时,他还是笔记本电脑最早的构想者和现代Windows GUI的建筑师。

近年来有一句话挺流行:“预测未来的最好办法,就是把它创造出来。”不少人误以为此言出自尼葛洛庞帝之口,实际上,这句话是阿伦·凯的名言。有很多人说布兰德是第一个使用PC一词的人,但布兰德说自己也是顺手牵羊,最早提出“PC”概念的就是阿伦·凯。20世纪90年代程序员设计的基本模式就是“面向对象”,发明这一术语的也是阿伦·凯。在20世纪70年代的一份备忘录上,阿伦·凯还正确预言到,“20世纪90年代将有成百万的个人计算机,而且都将连接到全球公用的信息设施上”,这不正是今天的互联网吗?

四、集成电路之父:罗伯特·诺伊斯

硅谷是传奇人士扎堆之地。但是一个人要想在硅谷同时获得财富、威望和成就,实在比登天还难。举目远眺大概只有罗伯特·诺伊斯(Robort Noyce)才是惟一一位三位于一体式的人物。

作为集成电路的发明者,诺伊斯在科学史上已名垂青史,这个具有划时代意义的发明促成了历史的大转折。而且他还与别人共同创办了两家硅谷最伟大的公司,第一家是半导体工业的摇篮——仙童(Fairchild)公司,这已成为历史;第二家则仍跻身美国最大的公司之列,这就是英特尔公司。他带着特有的神圣和威严,让同行和对手都得永远敬仰。以尖刻著称的硅谷杂志《Upside》敢对硅谷任何一位大腕儿进行任何刺激,但对诺伊斯却只能毕恭毕敬,在诺伊斯去世前几天的采访录,甚至成为杂志社经常炫耀的一种荣光。

在仙童,诺伊斯最大的成就是发明了集成电路。当基尔比在德州仪器用锗晶片研制集成电路时,诺伊斯和摩尔已把眼光直接盯住了硅晶片,因为硅的商业前景要远远超出锗。1959年2月,诺伊斯为“微型电路”申请了专利,但没有为他用平面处理技术制造的集成电路申请专利,直到同年7月才补全了这一手续。而此前德州仪器公司已宣布生产集成电路的产品,该公司的基尔比拥有第一个专利,但他的设计不实际,而诺伊斯则是第二个提出该专利的人。于是整个60年代,仙童和德仪相互控告,最后法庭将集成电路的发明专利授予了基尔比,而将关键的内部连接技术专利授予诺伊斯。诺伊斯的专利使仙童公司在沉闷的70年代得以存活下来,这一时期的仙童成为硅谷最具神话色彩的历史。

当然诺伊斯成就的最高峰还是英特尔公司,他与高登·摩尔和安迪·葛鲁夫一同创业,而且构建了业界极为罕见、完美和谐的三人“执政”局面。三人的合作只能说是天作之合,缺任何一位可能都会让英特尔历史大幅改写。诺伊斯自然是最耀眼的人物,传奇式的发明家、仙童公司的总经理和半导体业的“政治家”,他是英特尔公司的“脸面”。而甘于默默无闻的高登·摩尔则是公司的“心脏”,没有摩尔,英特尔不可能有足够的力量和士气;而没有强硬的葛鲁夫,英特尔甚至不会成为一家著名的大公司。

五、微处理器之父:特德·霍夫

1971年1月,第一个可以运转的微处理器诞生了,定名为“4004型”。其中,第一个“4”是指以4位为单位的设计思想,后一个“4”是指由英特尔制造的第4种专用芯片,而它的发明人就是特德·霍夫。霍夫认为自己占了天时和地利之便:“如果我们没有在1971年发明4004微处理器,那么别人也会在一两年里发明它。”

在普遍认为大型机才是大有可为的时代,霍夫另辟蹊径,投入到微处理器的研制中。霍夫说服了刚从仙童公司跳槽的斯坦·麦卓尔与他合作,共同设计了一种比4004型更强大的微处理器,称为“8008型”,这是第一个真正意义的微处理器。

1973年8月,“8080型”微处理器问世,它首次使用了MOS(金属氧化物半导体)工艺,成为有史以来最成功的微处理器之一,这也是第一个通用微处理器,是20世纪最后25年里一项具有划时代意义的发明。

著名的《经济学家》杂志将霍夫称作是“第二次大战以来最有影响的7位科学家之一”。1978年,他被提升为英特尔研究员(至今一共只有两个人获得过类似的称号),这意味着他在研究方面具有很大的自主权。

在评价微处理器和PC时,霍夫说:“我对微处理器在个人计算机中的应用感到非常惊讶,我也没有想到人们会仅仅为了业余的爱好而买微机。随着影像游戏机的发展,个人计算机成为人们又一种娱乐工具,任何一位发明家如果能够创造出什么来提供给人们娱乐,他就能获得成功。”

六、PC之父:爱德华·罗伯茨

创造出世界上第一台微电脑的殊荣,现在一般都归到爱德华·罗伯茨(Edward Roberts)身上。

罗伯茨是位电脑爱好者,1974年,罗伯茨决定利用8080微处理器装配一种供黑客试验的计算机,《大众电子》杂志为寻找独家新闻,主动上门观看了罗伯茨的设计方案,之后决定让他制成一台原型机,由杂志社在封面予以报道。

1975年1月,《大众电子》封面刊出一台很小的计算机照片,大字标题写着:“世界上第一组堪与商业机相媲美的以成套形式提供的小型计算机——牛郎星8800”。根据杂志的介绍,“牛郎星”勉勉强强算是一台电脑,在金属制成的小盒内,罗伯茨装进两块集成电路,一块即8080微处理芯片,另一块是存储器芯片。既没有可输入数据的键盘,也没有显示计算结果的“面孔”。插上电源后,使用者需要用手按下面板上的8个开关,把二进制数“0”或“1”输进机器。计算完成后,面板上的几排小灯泡忽明忽灭,就像军舰上用灯光发信号那样表示输出的结果。

就是这样一个简单的装置,却引发了大地震。罗伯茨的“牛郎星”电脑问世后,美国出现了一个电脑业余爱好者购买散件、在家庭车库内组装微电脑的热潮。 尽管“牛郎星”十分原始,但它把计算机发展到大型机时代料想不到的辉煌阶段。

七、商用软件之父:布莱克林

个人电脑的真正飓风是由AppleⅡ刮起的,而AppleⅡ成功的重要推进器就是VisiCalc电子表格软件。因为售价3000美元的AppleⅡ对家庭并没有多少吸引力,但配备了电子表格的AppleⅡ,就足以让人们把VisiCalc作为惟一的理由而购买它。从某种意义上说,AppleⅡ就是一台VisiCalc机器。

VisiCalc的发明人就是丹·布莱克林(Dan Bricklin)。1973年毕业后,布莱克林进入DEC,与他人合作编制了DEC的第一个字处理软件WPS-8。26岁时,布莱克林进入哈佛商学院寻求新的职业生涯,他在哈佛的分时计算机系统上用BASIC编写软件,进行财务计算。当时他常遇到的问题是,对不同的题目必须重新编写程序,于是他便开始思考能否用一种通用的计算模式来解决该问题。布莱克林用一个周末的时间粗粗地做出了一个演示版本。虽然这个演示版本是用BASIC写成的,速度很慢,而且行列只能添满一屏,但它已经具备电子表格的许多基本功能,此时已是1978年初。由于AppleⅡ等个人电脑产品的问世,布莱克林和麻省理工的老朋友富兰克斯顿一起合作,成立了软件艺术公司(SA),决定为AppleⅡ开发VisiCalc,发行商是丹·弗莱斯特拉的公司叫Personal软件公司(PS),可以说这是最早的微机应用软件公司。

电子表格VisiCalc的出现将PC从业余爱好者手中的玩具变成了炙手可热的商业工具,独立地改变了PC业的发展方向。布莱克林创造的不仅仅是一个产品、一家公司,而是整个软件产业。VisiCalc引发了真正的PC革命,它极大地激励了软件开发者,并从此宣告了PC商用化的到来。

八、IBM PC之父:埃斯特利奇

如果说个人电脑之火是由苹果引燃的,那么IBM的介入,才真正将这场大火燃遍全球,热度持续近20年而不减。而缔造IBM PC的,就是颇富个人魅力的唐·埃斯特利奇。

1980年中,IBM召集高层咨询会议,要对如火如荼的个人电脑浪潮作出应对。这时实验室主任洛伊站起来,提议打破常规,秘密组织一个精干小组,在一年内搞出PC来。 洛伊仅挑选了12名最优秀的工程师来演绎一段类似苹果公司经历过的传奇故事,担当这个名为“西洋棋”项目的负责人就是埃斯特利奇。以往,埃斯特利奇在工作上被认为“极不合作”,不听别人使唤,只凭自己的意思行事。而这种不合群的态度,正适合IBM PC计划,洛伊将它交给埃斯特利奇,事实证明这个选择十分英明。

1981年8月12日,IBM PC如人们预想的那样跨进了PC业,没有人惊奇和兴奋,因为要等一段时间,人们才真正明白PC时代的开始。在第一台PC发布前几个月,埃斯特利奇还着手下一代产品——PC XT的开发。XT的推出,再次把IBM推到PC科技的最前端,XT疯狂畅销,使IBM一举占有企业PC市场的75%。同时埃斯特利奇还启动另一计划,以PC攻打家庭市场,但推出时间太晚,错过了圣诞销售旺季,后来这个产品无疾而终。1982年,埃斯特利奇开始着手下一个大计划,即生产真正强劲的AT机。AT机象征着IBM是惟一能使用80286处理器的厂商。1984年 8月,AT机推出好几个月后,竞争对手才推出AT级产品。1984年, IBM PC的收入已达到40亿美元,这意味着光是PC一个部门就可以在美国工业公司中排名第74位,并可名列美国第三大计算机公司,仅次于IBM自己和DEC。埃斯特利奇还安排了一个争议性的计划,让经销商销售个人电脑,这是IBM产品第一次由非IBM业务代表的人销售, 从而开拓了电脑分销的先河。

1985年8月2日埃斯特利奇终于带着太太,去渡公司承诺已久的假期。两人乘坐的191航班试图在暴风雨中降落到达拉斯机场时,飞机失控,埃斯特利奇和太太玛丽不幸丧生。虽然他的生命结束于不幸的飞行事故,但打开昨日的篇章,历史永远会承认一个真正有贡献的人。

九:PC软件先锋:加里·基尔达尔

加里·基尔达尔被称为PC软件的开拓者,因为正是他打开了微处理器和微电脑之间的通道,在PC革命英特尔公司锋利的弹片中,有着基尔达尔历史性的贡献。

加里·基尔达尔敏锐地发现,4004微处理器可以用来编制程序,基尔达尔突然想到:“能不能在这里编制电脑的程序呢?”,这想法诞生了微程序(Microprogram)设计。基尔达尔在DEC公司的PDP-10小型机上为英特尔4004微处理器创建新的“微语言”后,英特尔马上聘请基尔达尔做技术顾问。在基尔达尔的主持下,创建了在个人电脑史上革命性的微处理程序设计语言PL/M(Programing language for Microprocessor)。这一新的语言随着Intel 8008、8080微处理器的进展,对个人电脑的革命起着巨大的推动作用。如果没有基尔达尔这一贡献,英特尔的微处理器肯定还会在计算器里“沉沦”许久,PL/M语言与Intel、Zilog、Motorola微处理器的结合,在70年代末,终于使微机的性能能同60年代的大型机和小型机相媲美。

另外,基尔达尔还是第一个光盘(CD-ROM)驱动程序的编写者,也是图形用户界面的先驱,当时还没有GUI(Graphic User Interface)的说法,基尔达尔把它叫做“图形环境管理员(Graphic Enviroment Manager)”。

十、电脑奇才:道格·恩格尔巴特

恩格尔巴特(Doug Engelbart)是电脑界的一位奇才,被称为“人机交互”领域里的大师。从20世纪60年代初期开始,他在人机交互方面做出了许多开创性的贡献,共发表论文30余篇,拥有20余项发明专利。世界上第一个电子邮件系统(E-Mail)、文字处理系统、在线呼叫集成系统和超文本链接都出自他之手。另外,他还发明了电脑显示器上的多重视窗、共享屏幕的电视会议、新的电脑交互输入设备等等。在恩格尔巴特的众多发明中,人们最熟悉的就是电脑上用的鼠标。1963年,美国国家专利局批准恩格尔巴特几年前提交的一份申请,确认一种叫“搜寻点击”的输入装置是一项独创的技术。在英语中,mouse有老鼠的意思,因此“搜寻点击”装置又被称为鼠标。1968年,恩格尔巴特应邀参加在旧金山举行的一次电脑会议,在会上,他拿出了许多令人吃惊的绝活:视窗(Windows)、超媒体(Supermedia)、群件(Groupware),还有鼠标,这也是鼠标第一次作为“搜寻工具”公开亮相。

十一、MS-DOS之父:蒂姆·帕特森

谁都知道MS-DOS是美国微软公司的产品,而且正是MS-DOS使微软公司实现了从一个不知名的软件开发公司到全球软件巨头的第一次飞跃。MS-DOS曾是微软公司的拳头产品,长期统治着个人电脑操作系统市场。虽然现在的微软“视窗”已经成为新一代PC操作系统霸主,但MS-DOS对业界的功劳仍不可磨灭。不过MS-DOS的真正主人蒂姆·帕特森的名字可能并不为每个人所知道。

帕特森在西雅图电脑制造公司任副总裁时,自己动手花了半年时间成功地推出了自己的操作系统,命名为SCP-DOS,本意为“快而粗糙的磁盘操作系统”,这个SCP-DOS便是现在DOS的前身。SCP-DOS推出之后,应用效果不错,但也曾被数据研究公司指责剽窃了他们当时颇受欢迎的CP/M操作系统。这两个操作系统确实有相似之处,不过 SCP-DOS在储存数据、组织文件等方面与CP/M有极大的不同。那么后来SCP-DOS如何成为MS-DOS呢?这还得从IBM的“西洋棋方案”说起。

1980年,IBM公司决心开发自己的个人电脑,便制定了“西洋棋方案”。他们需要找一家软件公司合作开发一套个人电脑操作系统。当时的微软为了不错过这个千载难逢的发展机会,向IBM称自己有软件操作系统,实际上,虽然当时微软公司在软件行业已有一席之地,但依靠的却是其程序语言,并无现成的操作系统。为了与IBM公司合作,微软不得不去找帕特森。

微软从帕特森那里,仅以2.5万美元的转让价格便获得了SCP-DOS的使用权。SCP-DOS虽比较粗糙,但已经具有了雏形,只要在其基础上进行加工,搞出合乎要求的产品并不太难。事实上,SCP-DOS对微软的重大意于义在于,它使IBM公司放弃了CP/M,转而与微软合作,从而成就了微软的未来。

1981年4月,帕特森离开了西雅图电脑制造公司,投到微软公司门下,这时才知道自己的操作系统被微软拿来作为IBM公司合作的产品之一。他当时非常恼火和后悔,不过也无可奈何,自己的成果虽然潜力无限,但在西雅图电脑制造公司却无法得到推广,相反由微软公司去发展完善,总比埋没了要好。

十二、便携计算机之父:亚当·奥斯本

在硅谷历史上,亚当·奥斯本(Adam Osborne)绝对算得上是一个人物,他在20世纪70年代初期得到了一份为英特尔新发明的微处理器编写说明书的工作,随后成为技术领域的自由撰稿人,先后在计算机杂志《界面时代》(Interface Age)和《Infoworld》上开辟专栏。

但奥斯本有更大的计划,他想要成为这个行业的一分子、硅谷的大亨,向对他的逻辑天才发生过怀疑的人证明他们的错误。他毫不谦虚,甚至有些自大地说:“我跟每一个人说,他们应该制造什么,可是没有人听我的话,所以我自己去制造了。”

令人惊奇的是,奥斯本证明了他的设想是合理的。奥斯本有两个很妙的主意:首先,利用眼下电路体积变得越来越小的优势,制造出一种既小又轻而且结实的便携式个人计算机;其次,把当时需单独购买并且价格昂贵的最流行软件,算在个人计算机的价格内卖给顾客。此前,硬件和软件公司从来不会同时提供这两项服务。

1980年3月,在西海岸计算机展览会上,奥斯本见到了为一家硬件公司设计电路板的Lee Felsenstein。奥斯本向他提出了自己的设想,并对Felsenstein提出设计要求:这台计算机一是要廉价结实,既小又轻;二是要捆绑字处理和电子表格软件。

1981年4月奥斯本Ⅰ型计算机全新亮相,含软件在内的整机价格仅1795美元。这一下子就轰动四方,到1981年9月,公司月销售额就攀升至100万美元,第二年公司收入就达7000万美元。

但奥斯本公司在成立的第二年的年中,便开始出现严重的错误。管理上的混乱导致产品质量下降、交货延误和财政空虚,而市场策略的错误更使它功亏一篑。当时在市场上占统治地位的是IBM,而奥斯本公司的“管理者”却不能与之兼容,这本不算太糟,但奥斯本不能忍受这样的情况。于是,奥斯本在新产品投放市场一星期后,宣布他已开始准备与IBM兼容,这等于无形之中宣布自己的产品已经过时,使销售量顿时一落千丈。一个美丽的计算机神话仅仅维持了不到两年时间。这个以自己的创新理念,促使计算机业发展方向发生革命的人物,这个一度是PC业内最具影响力、最富争议的人物,就这样从业界淡出,将一切甩在了自己的身后。

十三、磁盘之父:艾伦·舒加特

各种类型的软、硬磁盘,是个人电脑最重要的存储设备,磁盘的历史并不太长,从世界上第一台硬盘发明至今,也不过40余年时间。

20世纪50年代,IBM公司董事长小托马斯·沃森迅速把事业扩展到美国西海岸,下令在加利福尼亚圣何塞市附近新建实验室和工厂。约翰逊带领着30多名青年工程师,在不到三年时间,就为IBM创造了引人注目的技术成果——磁盘存储器。在约翰逊领导IBM圣何塞实验室研制硬盘的过程中,一位名叫艾伦·舒加特(Al.Shugart)的青年工程师发挥了关键作用。

舒加特1951年大学毕业后加盟IBM,在研究部门工作了十多年。 1969年,他离开IBM建立舒加特合伙人公司,并研制出世界上第一片以塑料材质为基础的5英寸软磁盘,即PC机上使用的标准软盘。

1974年,舒加特首次创办的公司倒闭,五年之后,舒加特重返电脑行业,在著名的硅谷腹地, 与过去的几位同事共同创建了希捷(Seagate)技术公司,专门为个人电脑研制高性能的小型硬盘。

1980年,希捷技术公司宣布研制出第一台5.25英寸温式硬盘,容量达5~10MB,后来成为IBM PC/XT个人电脑最具特点的标准配置。 舒加特领导的这家公司,目前已是资产数十亿美元、员工10余万人的世界上最大的PC硬盘生产厂商之一。

十四、自由软件之神:理查德·斯托尔曼

20世纪末,软件业发生的最大变革就是自由软件的全面复兴。在自由软件的浪潮下,软件业的商业模式脱胎换骨,从以卖程序代码为中心,转化为以服务为中心,而理查德·斯托尔曼则被称为软件业的自由之神。有人说,斯托尔曼应该算是世界上写软件最多的程序设计师。但是,斯托尔曼真正的力量是他的思想。在斯托尔曼的理论下,用户彼此拷贝软件不但不是“盗版”,而是体现了人类天性的互助美德。对斯托尔曼来说,自由是根本,用户可自由共享软件成果,随便拷贝和修改代码。他说:“想想看,如果有人同你说‘只要你保证不拷贝给其他人用的话,我就把这些宝贝拷贝给你’。其实,这样的人才是魔鬼”。

理查德·斯托尔曼一副披头士的打扮,看起来像现代都市里的野人,但如果他将一件“麻布僧袍”穿在身上,又戴上一顶圆形宽边帽子,有如绘画作品中环绕圣像头上的光环。一眨眼的功夫,他又变成圣人,散发着先知般的威严和力量。野人与圣人,恰恰就是这位自由软件的精神领袖理查德·斯托尔曼的双重属性,他既是当今商业软件领域野蛮的颠覆者,又是无数程序员和用户心目中神圣的自由之神。

十五、微软帝国:比尔·盖茨

据不久前的一期《福布斯》杂志的年度统计,微软创始人比尔·盖茨(Bill Gates)以587亿美元的个人资产仍排名世界首富。他在短短20多年的时间里创造的财富比传统的汽车大王、石油大王、钢铁大王或金融寡头在200年时间里创造的家庭财富还多。

像苹果砸出牛顿的智慧一样,个人电脑突入盖茨的脑海也有一个外在的启蒙者,这就是1975年1月份的《大众电子学》杂志,它封面上Altair 8080型计算机的图片一下子点燃了比尔·盖茨的电脑梦。盖茨打电话给罗伯茨表示要给Altair研制Basic语言,之后,盖茨和艾伦在哈佛阿肯计算机中心没日没夜地干了8周,为8008配上Basic语言,开辟了PC软件业的新路。

1975年5月,比尔·盖茨产生了退学的想法,他希望能和好友艾伦一起创办一个软件公司,由于父母的极力反对,比尔·盖茨没能马上退学,但他还是离开了西雅图到了亚帕克基。1975年7月,他与艾伦合作创建公司。微软公司前身成立时,比尔·盖茨正好20岁。

如今微软已成为了业内的“帝国”,除了主宰PC操作系统和办公软件外(这是微软的命脉),还涉足个人财务软件、教育及游戏软件、网络操作系统、商用电子邮件、数据库及工具软件、内部网服务器软件、手持设备软件、网络浏览器、网络电视、上网服务及近20个不同的Web网站。

十六、PC直销:迈克尔·戴尔

迈克·戴尔(Michael Dell)曾就读于奥斯汀的德克萨斯大学,19岁退学。

1984年,迈克·戴尔以1000美元和一个在个人计算机业中前所未有的理念建立了戴尔公司,即避开给产品增值较少的中间商,直接向最终用户销售量身订制的个人计算机。这样可以根据订单生产以取消库存,并把后勤服务与供应商结合起来,创造出一种规范化、低成本的企业文化。通过这种创新的直线订购方式和在业界率先倡导的服务和技术支持方案,戴尔公司已成为全球顶尖的个人计算机供应商之一,并且是领先的计算机直线订购公司和全球发展最快的主要计算机系统公司。

戴尔公司在PC的领导地位带来了全球革命,还被公认为是最大的计算机系统网上供应商,迈克·戴尔因此成为当时最年轻的首席执行官之一,他的个人资产曾达到214.9亿美元。

十七、苹果创始人:史蒂夫·乔布斯

不久前,美国《洛杉矶时报》评选出了“20世纪经济领域50名最有影响力人物”,史蒂夫·乔布斯(Steve Jobs)与另一名苹果电脑公司创办人沃兹·尼克并列第5名,他们的贡献主要表现为“创办苹果电脑,带动了全球个人电脑普及应用浪潮,并迫使IBM PC于1981年面市”。历经了20多年的磨炼,人们在史蒂夫·乔布斯身上发现了一系列走向成功的闪光之处:首先是信息消费技术产品的主导者,其次,是随机应变的企业家。

1976年,21岁的乔布斯和26岁的沃兹·尼艾克在乔布斯自家的车库里成立了苹果电脑公司。他们的第一个产品是一种没有键盘、机箱、声音和图像的计算机电路板,他们称之为Apple I。1977年4月他们成功开发了AppleⅡ,这是有史以来第一台具有彩色图形显示功能、键盘、电源和造型的个人电脑产品,也是第一台在市场上进行销售的个人电脑。1985年,苹果公司已经拥有了20亿美元的资产,成长为当时硅谷灿烂的明珠。

乔布斯的另一个功绩是在1997年9月重返该公司任首席执行官后,对奄奄一息的苹果公司进行大刀阔斧的公司改组和一连串新产品降价促销的措施。乔布斯抓住Internet浪潮带来的机遇,相继推出了Power Macintosh G3、iMac和iBook等一系列划时代产品,不仅让苹果电脑公司起死回生,从赤字累累奇迹般地变为连番获利,而且使苹果在1998第四个财政季度创造了1.09亿美元的利润。苹果重新回到了全球信息技术潮流领袖的地位,并带动全球个人电脑与信息技术产品时尚化、易用化的新潮流。

十八、以太网之父:鲍伯.梅特卡夫

鲍伯·梅特卡夫(Bob Metcalfo)被称为以太网之父,并且提出了网络的实用性与其使用者数目的平方成正比的“梅特卡夫法则”,即如果网络中有n个用户时,网络中就有n(n-1)个潜在商品,当第n+1个顾客加入此网时,该用户就向其他所有用户提供了2n个潜在商品。

鲍伯·梅特卡夫毕业于麻省理工学院,后来到哈佛念博士。他在哈佛大学宣读了阐述以太网的论文,哈佛大学说理论性不强,要他进行理论升华,然后再答辩。梅特卡夫无奈,只好到心理学家泰勒这里来“升华”,想不到却搞出惊人之举。在他主持下,施乐硅谷研究中心1973年5月,第一次在局域范围内实现了微机间的联网。梅特卡夫欣喜不已,当他要给这个新联网系统取名字时,一想到哈佛大学说他的理论深度不够,就气不打一处来,想到19世纪末物理学家们提出的玄虚不已的以太(Ether)理论,就郑重其事把它命名为“以太网”(Ethernet),并于1977年申请了专利。1979年4月,鲍伯·梅特卡夫正式成立了3Com公司,目标就是推进以太网成为业界标准。现在当以太网带宽开始向10G迈进时,谁还能说以太网不是业界的一个标准呢? IT偏执狂

葛鲁夫绝对是20世纪史上最重要的角色之一:他开创了微处理器产业、引爆了个人电脑革命并一手将英特尔打造成超级竞争机器。他的竞争策略是:推出新产品、主动降价打击竞争对手、再推出新产品……,这个逼迫自己不断进步,不让对手有任何喘息空间的策略,让英特尔主宰个个电脑产业的时间超过十年。现在他虽然已经退居二线,但葛鲁夫仍然是位值得研究的大师。

十九、英特尔:安迪·葛鲁夫

1998年1月5日,是葛鲁夫一生中最辉煌的时刻,他战胜了英国王妃戴安娜、克隆绵羊多莉之父伊安·威尔马特和美联储主席艾伦·格林斯潘,成为《时代周刊》新一届的年度世界风云人物,加上1997年英特尔辉煌的业绩,葛鲁夫的名声和威望被推上了巅峰。

而之后的葛鲁夫选择了急流勇退,1998年5月他将CEO一职交给公司总裁贝瑞特,只留下更具象征性的董事会主席一职。这一方面与他的年龄和身体状况有关,另一方面是处于战略转折点的CPU市场,迫使他提前让贤。此后,由于公司业绩不佳,加上低端市场操作不力,公司股票比高峰时下跌30%以上。葛鲁夫走得恰是时候,这位好斗、爱发脾气、有驾驭力的铁腕人物必须将权力之杖让与一个更和气、更具亲和力的人,才能使英特尔力挽狂澜。

二十、蓝色救星:路易斯·郭士纳

20世纪80年代末,将头埋在沙里的IBM公司经理们,面对新崛起的个人电脑还死抱着大型电脑的概念不放。20世纪90年代初期,由于欧美经济萧条,IBM公司内部机构臃肿,连续几年公司股票不断下跌,一时间,不少持悲观态度的人士认为,IBM已经难以逃脱覆舟的命运,当时的IBM几乎成了一辆没人要的破车。

1993年郭士纳正式接管IBM,开始发起向PC业的进军,重振IBM雄威。1994年底,IBM获得了自20世纪90年代以来的第一次赢利30亿美元。正如郭士纳所说,信息革命即将发生,IBM再也不能靠亮皮鞋和微笑来过关了。

1995年6月5日,处理完内部事务的郭士纳终于将锋芒扫向了外界。他瞄上了Lotus公司,不顾Lotus总裁吉姆·曼兹的反对,决定强行吞并。6月11日,这桩生意最终以35亿美元成交,成为当时软件史上最大的购并案。之后,郭士纳将Lotus的Notes软件作为武器,向软件市场发动总攻,并一举拿下了企业网络市场。1995年,IBM营收突破了700亿美元大关。

郭士纳为IBM带来了滚滚利润,也为他自己挣得了不菲的收入。1996年他已获得了82.5万股期权,账面价值6900万美元。1997年3月,董事会同意再给他增加30万股期权,希望他再干一个任期到2002年,为此公司将另加200万股票认购权。如果IBM股票能保持10%的增势,那这批股票将值3.3亿美元。

2008年8月2日星期六

Decorator模式

Decorator模式
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
ConcreteDecoratorB对象执行自己的Operation方法,然后调用Decorator类的Operation方法。这会调用ConcreteDecoratorB对徐爱那个之后的Component对象的Operation方法。
每个Decorator对象都对气候的对象封装自己的新功能。每个Decorator对象在被装饰的功能之前或之后执行自己的附加功能。
Decorator模式帮助我们将问题分解为两个部分:
  • 如何实现提供新功能的对象。
  • 如何为每种特定情况将对象组织起来。
将“Decorator对象的实现”与“判断如何使用它们的对象”相分离。这提高了内聚度,因为每个Decorator对象只关心自己添加的功能——而不关心自己如何被添加到对象链中。
Decorator模式的威力要求对象链的实例化与使用它的对象完全分离。最典型的实现方式是:使用工厂对象,在某些配置信息的基础上实例化对象链。
Decorator模式是为现有的功能动态添加附加功能的一种方法。实际情况要求创建一条对象链来提供需要的行为。对象链的第一个对象被客户对象调用,客户对象不关心对象链的创建。通过保持对象链的创建与使用的互相独立,添加功能的新需求不会对客户对象造成影响


Decorator模式:关键特征
意图 为一个对象动态连接附加的职责。

问题 你需要使用的对象执行你要求的基本功能。但是,你可能需要为这个对象添加某些功能,
这些附加功能可能发生在对象的基础功能之前或之后。(Java基础类在I/O处理中广泛使用了
Decorator模式)

解决方案 允许扩展一个对象的更能,而不必借助于子类型化。

参与者与协作者 Decorator对象为ConcreteComponent添加功能。有时候ConcreteComponent的派生类被用于提供核心功能,在这种情况下ConcreteComponent类就不再是具体的,而是抽象的。Component类定义了所有这些类使用的接口。

效果 被添加的功能属于小的对象。好处是可以在ConcreteComponent对象的功能之前或之后动
态添加功能。注意:虽然一个装饰着可以在被装饰者之前或之后添加功能,但对象链总是以ConcreteComponent对象结束。

实现 创建一个抽象类来表示原始的类和要添加到这个类上的新功能。在装饰者类中,将“对新功能的调用”放在“对紧随其后对象的调用”之前或之后,以获得正确的顺序。

2008年7月22日星期二

阿玛蒂亚·森:民主是一种普遍价值观

阿玛蒂亚·森:民主是一种普遍价值观
标签: 民主
阿玛蒂亚·森

(一九九八年经济学诺贝尔奖获得者阿玛蒂亚·森,是剑桥大学三一学院院长和哈佛大学拉蒙特荣誉教授。下面这篇论文是他一九九九年二月在印度新德里“建设世界民主运动”讨论会上的主调演讲。此次会议由国家民主基金会、印度产业联盟和新德里政策研究中心赞助。美国阿弗雷德·克诺夫出版社今年年底出版的阿玛蒂亚·森《自由的发展》一书,更详尽地讨论了本文的论点)

一九九七年夏天,日本一家重要报纸问我,二十世纪发生的最重要事件是什麽?这是一个启人思迪的问题。过去的一百年发生了不少重要事件。主宰十九世纪世界的一些欧洲帝国,特别是英帝国和法帝国,已走向结束。法西斯主义和纳粹主义兴起和灭亡。共产主义的兴盛和衰亡 ( 如前苏联 - 东欧集团 ) ,或发生剧烈改变 ( 如中国 ) 。西方国家居支配地位的世界经济转变为日本、东亚、东南亚具有更大优势的世界经济。虽然後者目前出现了一些金融和经济上的问题,但这并没有改变数十年来世界经济的这种发展趋势 ( 日本的经济转变花了将近一百年时间 ) 。过去的一百年的确发生了许多重要的事件。

尽管如此,在二十世纪出现的各项发展中,我毫无困难地挑选出一项该时期的最重要发展:民主的兴起。这并不是说其他的发展不重要。但我认为,人们在遥远的未来回顾本世纪发生的事件时,他们会发现,必须把民主制成为占优势地位的政府形式置於最重要的地位。 民主的观念当然起源於两千多年前的古希腊。包括印度在内的其他一些国家也有过一些零星的民主化尝试,但民主的观念确实形成於希腊,而且,在希腊崩溃并被更为威权主义的政府取代之前,民主被认真地,尽管是在一种有限程度上付诸实践。其他地方没有出现过任何形式的民主制度。

民主制作为一种可以运作的政府制度,是隔了很长一段时间之後,才慢慢重新出现并获得最终胜利。在这个过程中,有许多事件帮助了民主的复苏,包括一二一五年英国的大宪章运动,十八世纪的法国革命和美国革命,和十九世纪欧洲和北美选举权的扩大。然而,到二十世纪,民主才成为任何国家政府应具有的“常规”形式,无论这个国家是在欧洲、美洲、亚洲或非洲。

民主是一种普遍性制度,这一观念非常新颖,而且实质上是二十世纪的产物。用大宪章限制国王权力的英国反叛者们,将民主制完全视为地方性的需要。相比之下,追求美国独立的战士和法国革命者,对於民主成为一种普遍制度的发展贡献极大,但其实际要求的核心仍然是地方性的,在效果上仅限於大西洋两岸,并且以该地区特殊的经济、社会和政治历史为基础。

在整个十九世纪,政治理论家们讨论某个国家是否“适用於民主制”,这是很自然的事。只有在二十世纪,这种讨论才发生变化。政治理论家们认识到这个问题本身就是一个错误的问题:不需要判定某个国家是否适用於民主制,相反,国家必须通过民主制才能适应社会需要。将民主的适用范围扩展到具有不同历史、文化和富裕程度的数十亿人,这的确是一项惊人的变化。

正是在本世纪,人们终於接受“所有成人的普选权”必须包括“所有成人”,不仅包括男人还包括女人。今年一月我见到一位非常出名的女性 ---- 瑞士总统露丝·德雷佛斯,她使我回想起仅在四分之一世纪以前,瑞士妇女还没有投票权。我们终於认识到,民主的普遍性就像善行一样,是没有限制的。

我不否认,民主具有普遍性的说法受到了来自各种方向、采用各种形式的挑战。这也就是本文讨论的主题之一。我不得不讨论民主是一种普遍价值的观点及其相关的争论。但在讨论之前,我们一定要清楚认识到,民主已成为当今世界中一种处於优势地位的信念。

任何时代和社会都有一些处於优势地位的信念,它们就像电脑程序中的预设 (default) 指令组,被当做一种应该普遍遵守的规则。除非以某种方式明确地加以否定,它们的内容一般被认为是正确的。在世界各国尚未全部接受民主观念、也未全部采用民主制的情况下,民主制现已被普遍地认为是一种正确的制度。诋毁民主和反对民主的人,现在完全处於守势地位。

这一历史性变化是不久之前才发生的,当时主张民主制适合於亚洲和非洲的人处於绝望的境地。虽然我们现在有充足理由与那些公开或隐含地反对民主制的人展开论战,我们必须清楚看到,和数世纪以前相比,普遍的观念环境发生了多麽大的变化。某个国家 ( 南非、柬埔寨或智利 ) 是否“适用於民主制”这类问题,尽管在十九世纪的话语中非常流行,我们讨论时却无需每次都从头开始,因为我们现已认为这是理所当然的事。认识到民主是一种普遍适合的制度,并且正在成为一种普遍价值,这是思想史上的一场伟大革命,也是二十世纪的主要贡献之一。这就是我们讨论民主是一种普遍价值时所处的大环境。

印度的经验

民主的实践效果如何?现在没有人会真正怀疑民主在美国、英国、法国等国所起的好作用,但对於世界上许多较穷的国家,这仍然是一个颇有争议的话题。本文不打算详细探讨民主的历史记录,但我认为民主的实践效果相当好。

印度当然是这种争论的主要战场之一。英国人在反对印度独立时,非常怀疑印度人管理自己国家的能力。印度一九四七年独立时的状况确实非常混乱。印度政府缺乏经验,分治状态极不稳定,政治组合不明朗,加上普遍存在种族暴力和社会动乱。人们对於印度会成为一个民主的统一国家缺乏信心。但半个世纪以後,以和平手段解决困难问题的印度民主制,其实践效果相当好。政治分歧主要是通过法律来解决。按照选举和国会规则来组织政府。印度这个由各种不同成份草率组合起来的国家,却作为一个民主的政治单位而生存下来,并运作得相当好。它确实是通过实行民主而结为一体。

印度的生存经历了严重的挑战。这些挑战包括解决多种语言和多种宗教的问题。宗教和种族上的不同往往容易被宗派政客利用,而且确实在一些问题上受到利用 ( 例如最近数月发生的事件 ) ,从而引起全国的极大惊恐。但实际上,宗派暴力引起的惊恐,受到全国各阶层的谴责,这就为反对狭隘宗派主义最终提供了重要的民主保障。对於印度这样一个成份复杂国家的生存和兴旺,这是非常重要的保障。印度不仅有其主要的教派印度教,还拥有人数居世界第三的穆斯林教徒,数百万基督教和佛教徒,以及居世界第一的锡克教徒、帕西教徒和耆那教徒。

民主与经济发展

人们常说,非民主国家的经济发展速度更快。这种观点的提倡者是新加坡领袖和前总理李光耀,因而它有时被称为“李氏假说”。的确,南韩、新加坡和改革後的中国等威权国家的经济发展速度,高於印度、牙买加、哥斯达黎加等威权性较少的国家。然而李氏假设的根据是一些零星经验,和非常有选择性的有限资料,而不是对范围广泛的现有资料进行的普遍性统计研究。根据非常有选择性的资料,不可能建立这类普遍关系。我们不能把新加坡或中国的高速经济增长,作为威权国家更能促进经济发展的“确凿证据”。同样,我们也不能根据非洲的民主绿洲博茨瓦纳,在数十年内其经济增长率居非洲第一、在全世界也名列前茅,而得出相反结论。我们需要进行更多的系统性经验研究,才能得出结论。

事实上,没有可信的普遍证据可以证明,威权统治和压迫政治权利与公民权利确实有助於经济发展。普遍的统计资料的确不支持这种推论。罗伯特·巴洛 (Robert Barro) 或亚当.普泽沃斯基 (Adam Przeworski) 等人的系统性经验研究,并不支持政治权利与经济发展相冲突的观点。两者之间的定向关系可能取决於许多其他环境条件。有一些统计学研究提出,两者存在一种微弱的负向相关关系,另外一些研究却提出存在强烈的正向相关关系。综合考虑所有的比较研究之後可以看出,经济增长与民主之间很可能不存在任何方向的明确关系。虽然民主与政治自由本身极为重要,但两者的关系问题并没有获得解决。

这个问题还涉及经济学研究方法的基本问题。我们不仅研究统计学联系,还要研究与经济增长与发展有关的因果过程。对於导致东亚国家经济成功的经济政策和环境条件,我们现已有相当透彻的了解。尽管各种经验研究具有不同的重点,对於一系列有助於经济发展的政策,学术界已有广泛的共识,这些政策包括开放竞争,利用国际市场,鼓励投资和出口的公共政策,高水平的文化教育,成功的土地改革,以及扩大参与经济发展过程的其他社会机会。然而,没有理由假设,这些政策与民主相冲突,因而必须用南韩、新加坡和中国的威权主义手段来强力压制民主。相反,压倒性的证据证明,快速发展经济需要一种友好的经济环境,而不是一种严厉的政治制度。

为了全面考虑这个问题,我们必须超越狭隘的经济增长领域,考察更宽阔的经济发展需求,包括对经济与社会安全的需求。我们必须考察政治权利与公民权利,和防止严重灾难之间的关系。政治权利与公民权利使人民获得一个好机会,来提醒政府注意普通民众的需要、□□取合适的措施。政府对人民遭受严重灾难的反应,取决於它受到的压力。投票选举、批评、抗议等政治权利的表现,确实能够对政府的运作提供一种真正不同的政治鼓励机制。

我在其他地方讨论过一项重要规律,即在令人恐怖的世界饥荒史上,新闻自由具有相对独立地位的任何民主国家,从未发生过真正的饥荒。对於这个规律,我们无论在任何地方都找不出例外,无论是在最近发生饥荒的埃塞俄比亚、索马里等独裁国家,还是三十年代发生饥荒的苏联,或者一九五八至一九六一年大跃进失败後发生大饥荒的中国,或者在外国人统治时期发生饥荒的爱尔兰和印度。尽管在许多方面中国德经济发展比印度好得多,但中国仍然发生过饥荒,而且确实是全世界有史以来最严重的饥荒。中国一九五八至一九六一年的饥荒饿死近三千万人,而在整整三年内,中国政府的错误政策一直得不到纠正,其原因就在於中国没有议会中的反对党,没有新闻出版自由,没有多党制选举。由於没有人敢批评中国政府,即使每年饿死数百万人,其错误政策依然能够持续下去。现在北韩和苏丹的饥荒也属於类似情况。

饥荒似乎往往与自然灾害有关系。评论家经常简单地用自然灾害来解释发生饥荒的原因,如中国在大跃进期间发生水灾,埃塞俄比亚发生乾旱,或者北韩因天灾而农作物歉收。然而,其他许多国家也发生过类似的甚至更严重的自然灾害,但由於政府采取负责的干预措施,减轻了民众的饥饿,妥善地解决了饥荒问题。由於饥荒的主要受害者是穷人,政府可以通过雇佣计画等政策来提高穷人的收入,使饥荒受害者得到食物,从而防止民众的死亡。甚至在一些发生严重旱灾、水灾等天灾的最贫穷民主国家,如一九七三年的印度,八十年代初期的津巴布韦或博茨瓦纳,民众也能够吃饱肚子,而没有出现饥荒。

只要政府认真努力,饥荒并不难预防。而一个民主政府在面对选举、反对党和独立报纸的情况下,只能这样作。印度在独立之前被英国统治的时代,发生过多次饥荒。我记得印度最後一次饥荒是在一九四三年,即独立之前四年,我当时还是儿童。但在印度出现多党制和新闻自由之後,饥荒就消失了。

我的研究工作,特别是我和让.德累兹 (Jean Dreze) 的合作研究,考察过这个课题,所以我就不用在这里饶舌。饥荒问题仅仅是民主可以解决的例子之一,尽管在许多方面它是最容易分析的例子。在防止经济与社会灾难方面,政治权利与社会权利普遍扮演了正面角色。在正常情况下,人们也许不会怀念民主的这种工具作用。如果因为某种原因,经济情况恶化,民主制度所具有的政治鼓励机制,就会发挥巨大的实际作用。

这里有一个重要教训。许多专家治国论者在宣传市场制度可以提供经济鼓励机制的同时,却忽略了政治鼓励机制。他们选择了是一组极不均衡的基本规则。一个国家在走好运,没有严重灾害威胁,一切发展顺利的时候,人们不大会怀念民主的保护功能。但如果经济或其他条件发生变化,或者政策失误,一个似乎是健康的国家就潜伏著不安全的危险性。

最近东亚和东南亚出现的问题,就是不民主制度带来的惩罚。这在两个方面特别明显。首先,南韩、泰国、印尼等国发生的金融危机,与这些国家的商业运作缺乏透明度,特别是与金融政策缺乏公众的监督密切相关。导致这一危机的核心原因是缺乏一个有效的民主论坛。其次,一旦金融危机导致全面经济衰退,印尼等国的人们就特别怀念民主的保护功能,即民主国家防止饥荒的那种保护功能。在非民主国家,受害者没有地方发出他们的声音。

过去数十年来,这些国家的经济每年增长百分之五至百分之十,因而其国民生产总值减少百分之十似乎并不算严重问题。但如果经济收缩的负担没有被广泛地分担,而是集中在承受力最小的一部分失业者或者被解雇者身上,经济衰退就会严重破坏民众生活,使数百万人陷於悲惨境地。在经济良好时,印尼人民可能并不怀念民主。但在经济危机的分担很不平等的国家,民主的缺乏使人们发不出声音或者根本没有声音。人们在最需要民主的保护功能时,才会最强烈地怀念它。

民主的功能

到目前为止,本文的分析局限在民主的批评者、尤其是经济方面的批评者所限定的范围。在後面我将讨论民主的文化方面批评者的论点。我现在要从正面进一步分析民主所做的事,以及说它是一种普遍价值的根据。

民主究竟是什麽?我们绝不能把民主等同於多数人统治。民主的内容很复杂,它的确包括投票和尊重选举结果,但它还包括保护自由,尊重法律机构,保障自由讨论,和发表新闻和公正评论时不受政府的检查。如果不同派别没有获得充分机会表达自己的观点,或者选民没有获得新闻和思考不同观点的自由,选举也会变成一场大骗局。民主是一套需求系统,而不仅是在孤立情况下所选择的某种机械性的方法 ( 如多数决 ) 。

用这种观点来看,民主及其是普遍价值说法的优点,与某些特定美德及其自由实际很相似。我们可以分辨出民主丰富公民生活的三种方式。

首先,政治自由是人类普遍自由的一部分。实行公民权利与社会权利,是作为社会存在的个人,其幸福生活的关键组成部分。政治参与与社会参与对於人类的幸福生活具有天然的价值。人民不能参与社会政治生活是一种非常悲惨的处境。

第二,正如我在驳斥民主与经济发展相冲突的观点时所指出,在促使政府倾听人民发出的包括经济需求在内的各种需求的声音方面,民主具有一种重要的工具价值。

第三,实行民主可以为公民提供一个相互学习的机会,并有助於整个社会形成价值观和找到需要优先解决的问题。这一点需要作进一步分析。即使是理解“需求” ( 包括“经济需求” ) 的概念,也必须让公众对各种资讯、观点和分析进行讨论和交换意见。在这种意义上,民主除了具有在公民幸福生活的天然价值和政治决策方面的工具性价值外,还具有重要的建设性价值。我们在讨论民主的普遍价值时,必须进行这种多方面的分析。

要了解包括“经济需求”在内的人民的各种“需求”,就需要人民行使其政治权利和公民权利。要真正掌握经济需求的内容和及其影响,必须进行讨论和意见交换。政治权利和公民权利,特别是与保障人民公开讨论、辩论、批评和坚持异议有关的权利,乃是制订出资讯充分的、深思熟虑的政策这一过程的核心。这种过程对於形成社会的价值观与发现重要问题也极为重要。一般来说,没有公开的讨论,不进行公开地交换意见和争论,我们就不能发现需要优先处理的社会问题。

事实上,在评估社会与政治问题时,公开对话的范围和效果往往被低估。例如,公开讨论对於许多发展中国家的高生育率的降低,起著重要作用。大量证据表明,公开讨论高生育率对社区的恶劣後果,特别是对青年妇女生活的恶劣影响,对於印度文化水平较高地区生育率的显著下降,起了很大作用。印度喀拉拉邦或泰米尔纳德邦现在开始形成现代幸福家庭是小家庭的观念,这种观念的产生就与公众的广泛讨论有密切关系。喀拉拉邦现在的生育率为百分之一点七,与英国和法国差不多,却比中国的百分之一点九低。这种结果并非通过强制方法达到,而是由於社会形成了新的价值观,而政治对话与社会对话在这一过程中扮演了重要角色。喀拉拉邦民众,尤其是妇女的文化水平较高 ( 比中国任何省份都高 ) ,这也是社会政治对话成为可能的重要因素。

人类社会存在著各种悲剧与危险处境,其中有些比较容易通过社会手段来加以克服。人类的各种危险处境应该是我们辨识自己“需求”的根据。例如,有许多我们很向往的东西,可能被我们视为自己的“需求”。例如,我们可能像古人那样,希望自己长生不老。但我们并不把长生不老视为一种“需求”,因为显然做不到。我们关於“需要”的观念,与我们知道有些危险处境可以预防,而且知道其预防办法,有著密切的关系。在政府了解民众需求和相信政策的可行性 ( 特别是社会可行性 ) 的过程中,公共讨论扮演了关键角色。政治权利,包括自由表达与讨论的权利,不仅对於促进政府对经济需要作出反应很重要,对於了解经济需要的过程本身也非常重要。

价值的普遍性

如果上述分析正确,民主的价值就不仅在於它具有某一项优点,而在於它具有的许多优点。这些优点包括:第一,自由与政治参与在人类生活中的天然重要性;第二,在促使政府对公众需要负责方面,民主提供政治鼓励机制的工具重要性;第三,民主对於形成价值观、理解公众需要、权利和职责的建设性作用。根据这一分析,我们现在可以讨论本文的中心论点,即民主是一种普遍价值。

在讨论这个问题时,人们有时说,并非人人都同意民主具有决定性作用,尤其是把民主与引起我们向往的其他东西相比的时候更是如此。情况的确如此,这里不存在共识。但有些人将不存在共识当做民主并非普遍价值观的充分证据。

显然我们必须从方法论开始讨论:什麽是普遍价值?某种被视为普遍价值的东西是否必须要获得所有人的共识?如果必须如此,那麽普遍价值就可能不存在,因为没有哪种价值 ( 包括母爱 ) 没有遭到某些人的反对。我认为,普遍价值并不需要人人赞同,而是任何地方的人都可能有理由认为它是有价值的。

甘地提出非暴力是普遍价值的观点时,他没有说任何人都认为非暴力是自己的行动准则,而只是说任何人都有充分理由认为非暴力有价值。与此类似,泰戈尔提出思想自由是普遍价值时,也没有说所有人都接受这项原则,而是说所有人都有足够理由接受它,他对这些理由作了大量探索、说明和讨论。从这种角度来看,关於某种东西是普遍价值的任何主张,都与某些反事实的 (counterfactual) 分析有关,尤其是人们是否可以在他们尚未充分思考过的主张中看到某种价值。不仅是关於民主,所有关於普遍价值的主张,都隐含著这种假设。

我认为,正是在这种隐含性的假设方面,人们对民主的态度在二十世纪发生了最大的转变。对於某个没有民主的、许多人没有机会考虑民主制的国家,我们在讨论民主问题时,往往假设一旦民主变成他们的生活现实,那里的人民就会赞同它。十九世纪的人通常不作这种假设。这种被认为是天然的假设 ( 即我前面所说的“预设”立场 ) 在二十世纪发生了剧烈变化。

我还必须指出,这一变化在很大程度上是来自对二十世纪历史的考察。随著民主的扩展,民主的支持者是越来越多,而不是日益减少。起源於欧洲和美国的民主制度,现已扩散到地球的许多遥远角落,这些地方的人民自愿参与并接受民主制度。而且,如果某个民主制度遭到推翻,民众就会举行广泛的抗议,尽管这些抗议後来往往遭到残酷镇压。许多人□意冒著生命危险为恢复民主而战斗。

有些人反对民主是普遍价值,其理由并不是民主没有得到所有人赞同,而是各国的国情不同。这些不同的国情有时是指某些国家的贫穷。按照他们的说法,穷人关心的是面包,而不是民主。这种流行说法存在两个方面的错误。

首先,如上所述,民主的保护作用对於穷人特别重要。显然这适用於面临饥饿的饥荒受害者。它也适用於金融危机中从经济阶梯上摔下来的赤贫者。有经济需求的人需要在政治上发出自己声音。民主并不是一种要达到普遍富裕後才需要的奢侈品。

其次,没有证据证明,在可以选择的情况下,穷人会拒绝民主。七十年代中期,印度政府宣布在“紧急状态”取消各种政治权利与公民权利时,也提出了类似理由,在随後的选举中,选民们以不同的立场而分裂成旗帜鲜明的两派。在这场至关紧要的选举中,这个问题成为双方争论的焦点。大多数选民坚决反对取消基本的政治与於公民权利。印度是世界上最贫穷的国家之一,其选民对於其基本自由与权利的重视程度,超过对於经济困境的重视。

印度的历史经验,完全否定了穷人不关心公民政治权利的说法。考察南韩、泰国、孟加拉、巴基斯坦、缅甸、印尼等亚洲国家争取民主自由的斗争之後,我们可以得到相同结论。同样,尽管非洲国家普遍否定政治自由,一旦条件允许,那里就出现反对这种压迫的运动与抗议。

来自文化差异的理由

还有一些为民主的地区差异性辩护的论点,不是与经济环境有关,而是与文化差异有关。这些论点中最有名的也许是所谓的“亚洲价值观”,据说亚洲人具有重视纪律而不重视政治自由的传统,因而这些国家对民主必然持更为怀疑的态度。我在“卡内基道德与国际事务理事会”的讲座中比较详细地讨论了这种观点。

在亚洲文化史上,尤其是在印度、中东、伊朗和亚洲其他国家的古典传统中,我们很难找到支持这种观点的任何确实根据。例如,公元前三世纪印度帝王 Ashoka 的铭文中就有关於容忍多元主义、保护少数是国家职责的最早最明确的记载。

亚洲面积广袤,人口占全世界的百分之六十。对亚洲的多种民族归纳出普遍的结论很不容易。主张“亚洲价值观”的人有时首先将东亚当作特别适合这种主张的地区。尽管有人野心勃勃地主张,亚洲各国都很相似,但关於东西方差异的普遍命题往往以泰国以东的亚洲国家为例。我们应该感谢李光耀,他清晰而充分地解释了这种观点,而其他人的解释往往模糊不清。李光耀说,“西方关於社会和政府的观念与东方有根本不同”,“我所说的东亚,是指韩国、日本、中国、越南,它们与东南亚不同,後者是中国文化与印度文化的混和物,尽管印度文化本身也强调类似的价值观”。

然而,在东亚的内部,不仅在日本、中国、韩国和其他国家之间,而且在每一个国家内部,存在著的差异很大的文化成份。人们在解释“亚洲价值观”时经常引用孔子的话,但这些国家的文化不仅受到孔子的影响,也受到其他影响。例如,日本、中国和韩国的佛教传统,历史悠久而影响广泛,在一千五百多年内具有很大势力。另外,这些国家还受到基督教的相当大影响。这些国家中,没有哪个国家存在一种崇尚秩序胜於崇尚自由的均质文化。

而且,孔子本人也不主张对国家的盲目崇拜。子路曾向他请教如何为君王服务,孔子的回答可能要引起当今威权政府新闻检查官的怀疑。他说:“即使得罪君王也要讲真话” ( 《论语·宪问篇》:“子路问事君,子曰勿欺也而犯之” ) 。孔子并非反对在现实中要谨慎和讲究策略,而是主张在必要时人民可以反对坏的政府。他说:“如果政府表现好,要大胆说话和行事;如果政府表现不好,要行事勇敢但说话温和。” ( 论语·宪问篇》:“邦有道危言危行,邦无道危行言逊” ) 。

孔子确实明确指出,想象中的宏伟“亚洲价值观”的两个标尺,即对国家的忠诚 ( 忠君 ) 与对家庭的忠诚 ( 孝 ) 之间,可能发生严重冲突。许多主张亚洲价值观的人认为国家角色是家庭角色的延伸。但正如孔子所说,两者是相互冲突的。叶公对孔子说:“我有一个刚直不阿的邻人,他父亲偷了一只羊,他就谴责自己的父亲。”孔子答道:“在我的邻人中间,刚直不阿的人行事不同:父子相互掩盖,这也是刚直不阿。” ( 《论语·子路篇》:“叶公语孔子曰:吾党有直躬者,其父攘羊而子责之。孔子曰:吾党之直者异於是,父为子隐,子为父隐,直在其中矣。” )

将亚洲价值观单一地解释为反对民主与政治权利,这种观点经不起严格推敲。我们不应该过於严格地批评这类观点缺乏学术证据,因为提出这类观点的并不是学者而是政客,而且往往是威权政府的正式或非正式的代言人。有趣的是,我们学者对实际政治的态度也许不大现实,但现实政客讨论学术问题的态度却非常不实事求是。

当然,在亚洲传统中不难找到关於威权主义的记述,但西方经典中也很容易发现这类记载。只要查一下柏拉图或者阿奎纳 (Aquinas) 的著作,就可发现崇尚纪律并非亚洲的专利品。仅仅因亚洲存在一些关於纪律和秩序的记载,就否定民主是普遍价值的可能性,就犹如根据柏拉图或阿奎纳的著作 ( 姑且不提欧洲中世纪的大量赞成宗教裁判的著作 ) ,而反对民主可能是现今欧洲或美国政府的一种自然形式。

由於当代世界尤其是中东的政治斗争经验,人们常常把伊斯兰教描绘成根本不容忍或敌视个人的自由。但同一文化传统内存在著多样性的规律同样适用於伊斯兰教。印度的阿克巴及其他大多数莫卧尔王朝帝王 (Aurangzeb 是明显例外 ) ,是在理论与实践上实行政治宽容和宗教宽容的的最佳范例。土耳其的帝王比同时代的欧洲帝王更为宽容。开罗和巴格达也有不少类似例子。十二世纪的伟大犹太学者 Maimonides 不得不逃离其出生地 ---- 不宽容的、迫害犹太人的欧洲,在宽容的开罗得到萨拉丁苏丹的庇护从而获得安全。

多样性是世界上大多数文化的特徵。西方文明也不例外。民主在现代欧洲国家获得胜利,这主要是欧洲自启蒙运动和工业革命以来,特别是在二十世纪逐渐形成一项共识的结果。把这个现象解释为西方一千多年来对於民主的历史使命,然後与非西方传统 ( 把每一种非西方传统视为一种单质文化 ) 对比,这是一种绝大的错误。这种过於简单化的倾向,不仅存在於一些亚洲国家政府发言人的著作,也存在於一些西方学者的著作中。

让我举一位重要学者的著作为例,在其他许多方面,这位学者的著作给人留下了深刻印象。这就是杭亭顿关於文明冲突的著作。他没有充分认识到各种文化的多元性。他明确地得出结论说:在文明社会中处於独特地位的西方,存在著“一种个人主义观念和关於权利与自由的传统”。杭亭顿还说:“在西方现代化之前,西方文明就出现了不同於其他文明的核心特徵。”他认为,“在西方现代化之前很久,西方就已经是西方”。我认为,这一论点经不起历史的检验。

对於亚洲国家政府发言人的所谓“亚洲价值观”与所谓西方价值观相对立的每一种说法,似乎存在著西方知识份子从另一角度得出的相应说法。假设对於亚洲的每一种说法,西方都有势均力敌的说法与之相对应。即使把双方的说法加在一起,也无法否定民主是一种普遍价值。

结 论

我已经讨论了有关民主是一种普遍价值的许多问题。民主的价值包括其在人类生活中的天然重要性,在产生政治鼓励机制方面的工具性作用,以及在形成社会价值,在了解民众需求、权利、职责方面的效力和政策可行性方面的建设性功能。这些优越性并不具有地区性特徵。崇尚纪律与秩序也不具有地区性特徵。价值的多元性似乎是大多数,甚至是所有文化的特徵。文化差异方面的讨论并不排斥,也不能限制我们现在可以作出的选择。

我们现在必须作出这种选择,特别是要强调民主的功能性作用,它是当今世界的民主制赖以立足的基础。我已经指出,用这样的方式来分析民主,具有强大的说服力,而且不受地区的局限。民主是一种普遍价值的主张,其最终的理由就来自这种分析。这就是本文讨论的核心。如果从来自不同历史背景的、假想的文化忌禁或假设的文明先决条件出发,就不可能得到这一结论。

□( 曹思华译,参考文献从略。)

2008年7月9日星期三

Google Lively

Google最新推出Lively 服务,为用户创建一个虚拟的聊天环境,下面是个叫Lost的场景,挺酷的,不过刚开始用似乎挺麻烦的,进入房间后可以用鼠标任意拖动。试试...

2008年7月1日星期二

《大腕》之程序员篇

一定得是N层结构,
层数越多越好,层少了用户误会我们不重视,
什么数据访问层呀,实体控制层啊,
能给他加上的全加上。

程序员一定都得是老鸟,30一下的基本不考虑,
还得是清一色的外企空降兵,
都有10年以上的编程经验的那种,用过的语言越多越好,
编程都不带查MSDN的,牛吧!
程序员各个都配IBM笔记本,
CPU要3G以上的,内存硬盘和屏幕都要最大的,
扩展槽别剩下,能插上的全插上。
能安的操作系统全安上,
开机一屏幕上就一堆系统等你选,
倍有面子!

系统平台就得是J2EE,
人家竞争对手除了C++就是Java,
你要用.NET都不好意思和别人打招呼。
你说这样的系统设计出来得卖多少钱?
我觉得怎么着也得100万吧?
100万,那是单机版!
1000万起!
你还别嫌太贵,还不免实施服务费。
你得研究有钱用户的心理,
愿意花1000万买这套软件用的,
根本不在乎多花上几百万?

什么叫软件泡沫,你知道什么?
软件泡沫就是做都做最复杂的,
用就得用最贵的,还得特难用,显的用户水平高。

所以我们搞软的口号就是,
不求好用,但求费劲!

2008年6月24日星期二

美国兰德公司对中国人的评价

美国兰德公司对中国人的评价

美国兰德公司是一家著名的非盈利的研究机构,为美国官方提供"客观的分析和有效的解决方案"。最近,他们公布了一份对中国现状分析报告,即有肯定,也有严厉批评,值得国人反省。本文观点来自兰德公司亚太政策中心

如果20世纪的中国是一个富裕和统一的国家,我们会有一个完全不同的第一次世界大战,我们就不会有第二次世界大战而是第二次欧洲大战。 中国能够阻止日本侵略或者打败日本。美国在这些冲突上的花费从根本意义上会减少很多,因为珍珠港事件不会发生。我们和整个世界,更不用说10亿中国人,一 个多世纪以来,已经为中国的弱小付出了惨重的代价。世界需要一个健康的中国。

中国的需求对日本走出衰退起到了促进作用。日本状况给世界经济带来了风险。关于这一点,怎么说都不夸张。日本巨额的债务会产生多米诺骨 牌效应,逐渐波及到全世界。在中国有力的帮助下,危险似乎已经过去。中国全球化给美国带来了很多影响。最明显的是,中国成为美国商品最大的市场。

可口可乐早就完成了那个看上去像是神话的目标:卖10亿瓶可口可乐;曾经嘲笑中国梦的通用在中国卖了很多的别克汽车,在困难时期,中国 带来的利润占通用利润的很大一部分;中国联想购买IBM个人电脑业务,挽救了这个垂死部门的工作岗位。中国提供更低价的生活必需品给美国人的生活水平做出 了很大的贡献,尤其是对我们不是那么富裕的居民而言。有迹象表明由于能够购买中国低价的出口货物,低收入美国人的生活水平可能提高了5%到10%。

中国金融体系的不合理意味著中国建造了垂死企业,导致巨大的生产力过剩。近些年来,中国财政政策上的反复无常导致过度建造,对铁、铝、 水泥和其他原材料产生了巨大的需求。日本人和现在的中国人看上去似乎会买下世界上所有的东西,但是当你看到他们的财政状况的潜在问题时,你会发现一个黑 洞。日本人在90年代陷入了这样一个黑洞,至今还在努力地爬出来。中国人很多年后仍将会为目前这种无节制的狂热的购买行为感到心痛。

目前,中国面临著巨大的挑战。中国的银行是我们所知道的世界上最糟糕的银行。中国每一代,都有相当于美国规模的人口从农村涌入城市。每 年,都有1200-1300万新工人加入就业大军。在制造业,生产力对就业的影响比我们国家要严重得多。到2020年,中国人口老龄化会使工作人口与不工 作人口的比率成为世界上最糟糕的,比日本更甚。如果没有特效的新政策的话,中国的经济在那个时期就会狠狠地撞墙。到2020年,以我们的标准来看,它会是 一个非常穷的国家。

中国人缺乏诚信和社会责任感。中国人不了解他们作为社会个体应该对国家和社会所承担的责任和义务。普通中国人通常只关心他们的家庭和亲属,中国的文化是建立在家族血缘关系上而不是建立在一个理性的社会基础之上。中国人只在乎他们直系亲属的福址,对与自己毫不相关的人所遭受的苦难则视而不见。毫无疑问,这种以血缘关系为基础的道德观势必导致自私,冷酷,这种自私和冷酷已经成为阻碍中国社会向前发展的最关键因素。

中国从来就没有成为一个法制社会,因为中国人的思维方式与守法行为格格不入。中国人老想走捷径。他们不明白这样一个事实:即成就来自于与努力工作和牺牲。中国人倾向于索取而不给予。他们需要明白一个道理:生活的真蒂不在于你你索取多少而在于你能给予社会和你的人类同胞多少。

大多数中国人从来就没有学到过什么是体面和尊敬的生活意义。中国人普遍不懂得如何为了个人和社会的福址去进行富有成效的生活。潜意识里,中国人视他们的生活目的就是抬高自己从而获得别人的认知。这样一来,一个人就会对"保有面子"这样微不足道欲望感到满足。"面子"是中国人心理最基本 的组成部分,它已经成为了中国人难以克服的障碍,阻碍中国人接受真理并尝试富有意义的生活。

这个应受谴责的习性使得中国人生来就具有无情和自私的特点,它已成为中国落后的主要原因。

中国人没有勇气追求他们认为正确的事情。首先,他们没有从错误中筛选正确事物的能力,因为他们的思想被贪婪所占据。再有,就算他们有能力筛选出正确的事情,他们也缺乏勇气把真理化为实践。

中国人习惯接受廉价和免费的事物,他们总是梦想奇迹或者好运,因为他们不愿意付出努力,他们总想不劳而获。很少有中国人明白一个事实, 就是威望和成就是通过一步步努力的工作和牺牲实现的,不付出就没有所得。简单来说,如果是为了谋生,那一个人只有去索取;但如果是为了生活,一个人必须要 去奉献。

由于在贫穷的环境下生长并且缺少应有的教育,大多数中国人不懂得优雅的举止和基本的礼貌。他们中的大多数人着装笨拙粗鄙却不感到害羞。他们在青少年时所受的教育就是如何说谎并从别人那里索取,而不是去与别人去分享自己的所有。

中国是一个物产丰富的国家。但无限制生育政策所带来恶果使得中国成为了无限廉价劳动力的输出国。这些输出也包括那些受过教育的劳力输出,除了他们的教育水平,实则和其他一般苦力没有本质上的区别。

中国大规模生产的便宜产品降低了输入这些产品的地区的商业信用度。由于技术落后,管理失败,中国制造的单位能耗要比发达国家如日本,美国高出很多。因此,随着出口额的增加,中国在扩大生产的同时丧失着宝贵的能源。同时,这种行为也严重的污染了环境,使中国变为全世界最不适宜人类居住的国家。

目前中国正在遭受着资本主义社会2大邪恶的折磨,即环境的破坏与人性的丧失。由于中国人天生的贪婪的本性,它们可以毫无保留的接受资本主义的阴暗面即无止境的追求利润,忽视人的尊严。中国人对西方的技术与产品狂热追求却对西方管理文化所强调的坦率,直接,诚实这些品质漠不关心。

由于中国文化不鼓励敢于冒险这种优良品质,所以中国人极力避免冒险,他们也不想寻求机会来改善自己的生活。中国人对于生活的平衡性和意义性并不感兴趣,相反他们更执迷于对物质的索取,这点上要远远胜于西方人。大多数中国人发现他们不懂得"精神灵性","自由信仰"以及"心智健康"这样的 概念,因为他们的思想尚不能达到一个生命(补:即肉体和灵性的并存)存在的更高层次。他们的思想还停留在专注于动物本能对性和食物那点贪婪可怜的欲望上。

在中国人的眼中,受教育不是为了寻求真理或者改善生活质量,而只是身份和显赫地位的象征和标志。中国的知识分子从别人那里得到尊敬并不 是因为他们为了别人的幸福做过什么,而只是因为他们获得占有了相当的知识。事实上,他们中的大多数只不过是一群仅仅通晓考试却从不关心真理和道德的食客。

中国的教育体系很大程度上已经成为一种失败和耻辱。它已经不能够服务于教育本应所服务的对象:社会。这个教育体系不能提供给社会许多有用的个体。它只是制造出一群投机分子,他们渴望能够受益于社会所提供的好处却毫不关心回报。

中国可以培养出大批的高级能人才,但却很少可以培养出合格的可以独立主持的管理级专家。服务于一个公司或者社会,光有技术是不够的;还 需要有勇气,胆量,正直和诚实的领导才能,这恰恰是大多数中国人所缺少的品性。正如亚瑟.史密斯,一位著名的西方传教士一个世纪前所指出的,中国人最缺乏 的不是智慧,而是勇气和正直的纯正品性。这个评价,虽然历经百年,如今依旧准确诊断出中国综合症的病因。

大多数中国毕业生对选择出国并为外国工作不会感到内疚,事实上他们首先欠下了中国人民在教育上为他们所做出的牺牲。随着传统文化价值观的破坏和逐步衰弱,大多数的中国人,包括受过教育的人都徘徊在精神和内心世界的路口,像迷失的狗一样不知何去何从。

2008年6月7日星期六

阿玛蒂亚·森:民主是一种普遍价值观

Design Patterns

面向对象范式的核心是“对象”的概念。所有的东西都聚焦于对象。围绕对象——而非函数——组织代码。
什么是对象?对象最初被定义为“拥有方法(面向对象版本的函数)的数据”。很不幸,这种看待对象的观点有很大的局限性。
有种对象技术是:对象的识别来自于对问题领域中实体的观察。观察这些实体需要做些什么,我为每个对象确定他们的责任(或方法);
更有用的定义是基于概念视角的定义——对象是拥有责任的实体。这些责任让对象拥有自己的行为。对象应该对自己负责,并且这种责任应该被清楚地定义出来。
这是一个更好的定义,因为他帮助我将注意力集中在“对象应该做什么”,而不是仅仅是“如何实现他们”。这让我可以分两步构建软件:
1.建立一个初步的设计,不必担心涉及的任何细节。
2.实现前面一个步骤得到的设计。
最后,这样的视角让我可以得到更好的对象选择及定义(在某种意义上面这是任何涉及的要点)。对象定义将更灵活;通过关注对象“做什么”,我们可以借助继承在需要的是有使用不同的、特定的行为。如果集中注意力与实现细节,我们也许可以得到这样的效果,但要获得相应的灵活性就必须付出更高的代价。
按照责任来考虑问题可以使问题更简单化,因为这样可以帮助我们定义对象的公共接口。如果对象有某种责任,就一定有某种途径要求他履行自己的责任。但是,这并不是对对象内容做任何的暗示。关于对象的责任信息甚至可以不再这个对象内部。
“关注动机而不是实现”的情景在设计模式中反复出现。
用这样的方法看待对象。让它成为你对对象的基本观点。如果你这样做了,你将获得出众的设计。
摘自:Design Patters Explained-Alan Shalloway & James R.Trott

对象, 设计模式

学习设计模式的理由:
  • 复用解决方案——通过复用已经建立的设计,我为自己的问题找到更高的起点并避免了绕弯路。我受益于学习别人的经验。我不必再为普通、重复的问题重新设计解决方案。
  • 建立通用的术语——交流与协作都需要一个共同的词汇基础、一个对问题的共同观点。设计模式在项目的分析和设计简短提供了一个通用的参考点。
  • 对于问题、设计过程和面向对象,模式给你一个更高层次的视角。这样的视角将你从“过早处理细节”的“暴政”中解放初来。
  • 复用现有的、高质量的、针对常见的重复出现问题的解决方案。
  • 建立通过术语一改善团队内部的沟通。
  • 将思考转移到更高的视角。
  • 判断是否拥有正确的设计,而不是仅仅一个可以运行的设计。
  • 改善代码的可修改性。
  • 促进对改良设计的选用,甚至在没有明确使用模式的时候。
  • 发现“庞大的继承体系”的替代方案。

创建优秀面向对象设计:
  • 针对接口变编程。
  • 优化使用对象组合,而不是类继承。
  • 找到并封装变化点。
摘自: Design Patters Explained-Alan Shalloway & James R.Trott

设计模式

2008年5月30日星期五

JSP数据库连接池的必要性

JSP数据库连接池的必要性



-
一般情况下,在使用开发基于数据库的WEB程序时,传统的模式基本是按以下步骤:
  1. 在主程序(如Servlet、Beans)中建立数据库连接。
  2. 进行SQL操作,取出数据。
  3. 断开数据库连接。
  使用这种模式开发,存在很多问题。首先,我们要为每一次WEB请求(例如察看某一篇文章的内容)建立一次数据库连接,对于一次或几次操作来讲,或许你觉察不到系统的开销,但是,对于WEB程序来讲,即使在某一较短的时间段内,其操作请求数也远远不是一两次,而是数十上百次(想想全世界的网友都有可能在您的网页上查找资料),在这种情况下,系统开销是相当大的。事实上,在一个基于数据库的WEB系统中,建立数据库连接的操作将是系统中代价最大的操作之一。很多时候,可能您的网站速度瓶颈就在于此。
  其次,使用传统的模式,你必须去管理每一个连接,确保他们能被正确关闭,如果出现程序异常而导致某些连接未能关闭,将导致数据库系统中的内存泄露,最终我们将不得不重启数据库。
  针对以上问题,我们首先想到可以采用一个全局的Connection对象,创建后就不关闭,以后程序一直使用它,这样就不存在每次创建、关闭连接的问题了。但是,同一个连接使用次数过多,将会导致连接的不稳定,进而会导致WEB SERVER的频频重启。故而,这种方法也不可取。实际上,我们可以使用连接池技术来解决上述问题。首先,介绍一下连接池技术的基本原理。顾名思义,连接池最基本的思想就是预先建立一些连接放置于内存对象中以备使用:
 

   
如图所示,当程序中需要建立数据库连接时,只须从内存中取一个来用而不用新建。同样,使用完毕后,只需放回内存即可。而连接的建立、断开都有连接池自身来管理。同时,我们还可以通过设置连接池的参数来控制连接池中的连接数、每个连接的最大使用次数等等。通过使用连接池,将大大提高程序效率,同时,我们可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。下面我们以一个名为ConnectionPool的连接池为例来看看连接池的实现。先看看ConnectionPool的基本属性:
  m_ConnectionPoolSize:连接池中连接数量下限
  m_ConnectionPoolMax:连接池中连接数量上限
  m_ConnectionUseCount:一个连接的最大使用次数
  m_ConnectionTimeout:一个连接的最长空闲时间
  m_MaxConnections = -1:同一时间的最大连接数
  m_timer:定时器
  这些属性定义了连接池与其中的每个连接的有效状态值。连接池的自我管理,实际上就是通过定时的对每个连接的状态、连接的数量进行判断而进行相应操作。其管理流程如下:


通过上图,我们可以定义出ConnectionPool要完成管理所需要的基本接口:
public class ConnectionPool implements TimerListener{
  public boolean initialize() //连接池初始化
  public void destroy() //连接池的销毁
  public synchronized java.sql.Connection getConnection() //取一个连接
  public synchronized void close() //关闭一个连接
  private synchronized void removeFromPool() //把一个连接从连接池中删除
  private synchronized void fillPool() //维护连接池大小
  public synchronized void TimerEvent() //定时器事件处理函数
}
  通过这几个接口,已经可以完成连接池的基本管理。在TimeEvent()函数中完成连接池的状态检验工作,fillPool()时连接池至少保持最小连接数。因为我们要保存每一个连接的状态,所以还需要一个数据库连接对象:
class ConnectionObject{
  public java.sql.Connection con; public boolean inUse; //是否被使用标志
  public long lastAccess; //最近一次开始使用时间
  public int useCount; //被使用次数
}
加入了ConnectionObject对象后,在ConnectionPool中操作的应该只是ConnectionObject,而其他进程需要的只是ConnectionObject的con属性,因此我们再加入一个类,作为其他进程获得与返回连接的接口: CLASS Conn{
  GetConnection(); //从连接池中取出一个有效连接
  CloseConnection(); //返回连接,此时并没有关闭连接,只是放回了连接池
  DestroyPool(); //销毁连接池
}
  最后我们的整个系统总的架构如下:
     


通过上面的介绍,我们可以看出,连接池技术的关键就是其自身的管理机制,以上的管理流程只是本人一点见解,关键是想向大家介绍一种思路,在此基础上,您可以进一步完善连接池技术为您所用。

2008年5月24日星期六

Struts,MVC 的一种开放源码实

Struts,MVC 的一种开放源码实现

用这种 servlet 和 JSP 框架管理复杂的大型网站

developerWorks
文档选项
将此页作为电子邮件发送

将此页作为电子邮件发送


级别: 初级

Malcolm Davis (malcolm@nuearth.com), 顾问

2001 年 2 月 23 日

本文介绍 Struts,它是使用 servlet 和 JavaServer Pages 技术的一种 Model-View-Controller 实现。Struts 可帮助您控制 Web 项目中的变化并提高专业化水平。尽管您可能永远不会用 Struts 实现一个系统,但您可以将其中的一些思想用于您以后的 servlet 和 JSP 网页的实现中。

简介

小学生也可以在因特网上发布 HTML 网页。但是,小学生的网页和专业开发的网站有质的区别。网页设计人员(或者 HTML 开发人员)必须理解颜色、用户、生产流程、网页布局、浏览器兼容性、图像创建和 JavaScript 等等。设计漂亮的网站需要做大量的工作,大多数 Java 开发人员更注重创建优美的对象接口,而不是用户界面。JavaServer Pages (JSP) 技术为网页设计人员和 Java 开发人员提供了一种联系钮带。

如果您开发过大型 Web 应用程序,您就理解 变化 这个词的含义。“模型-视图-控制器”(MVC) 就是用来帮助您控制变化的一种设计模式。MVC 减弱了业务逻辑接口和数据接口之间的耦合。Struts 是一种 MVC 实现,它将 Servlet 2.2 和 JSP 1.1 标记(属于 J2EE 规范)用作实现的一部分。尽管您可能永远不会用 Struts 实现一个系统,但了解一下 Struts 或许使您能将其中的一些思想用于您以后的 Servlet 的 JSP 实现中。

在本文中,我将以一个 JSP 文件为起点讨论该网页的优缺点,该文件中使用的元素可能是您所熟悉的。随后我将讨论 Struts,并说明它是如何控制您的 Web 项目中的变化并提高专业化水平的。最后,我将重新开发这个简单的 JSP 文件,在开发过程中我已顾及到网页设计人员和变化。





回页首


一个 JSP 文件就是一个 Java servlet

JavaServer Page (JSP) 文件只是审视 servlet 的另一种方式。JSP 文件的概念使我们能够将 Java servlet 看作一个 HTML 网页。JSP 消除了 Java 代码中经常出现的讨厌的 print() 语句。JSP 文件首先被预处理为 .java 文件,然后再编译为 .class 文件。如果您使用的是 Tomcat,则可以在 work 目录下查看预处理后的 .java 文件。别的容器可能将 .java.class 文件存储在其他位置;这个位置与容器有关。图 1 说明了从 JSP 文件到 servlet 的流程。


图 1. 从 JSP 文件到 servlet 的流程
JSP to servlet flow

(这与 Microsoft 的 Active Server Page (ASP) 明显不同。ASP 被编译到内存中,而不是编译到一个单独的文件中。)

简单的独立 JSP 文件

在小型 JSP 应用程序中,经常会看到数据、业务逻辑和用户界面被组合在一个代码模块中。此外,应用程序通常还包含用来控制应用程序流程的逻辑。清单 1 和图 2 展示了允许用户加入一个邮件列表的一个简单 JSP 文件。


清单 1. join.jsp -- 一个简单的请求和响应 JSP 文件
<%@ page language="java" %> <%@ page import="business.util.Validation" %> <%@ page import="business.db.MailingList" %> <% String error = ""; String email = request.getParameter("email"); // 是否有电子邮件地址 if( email!=null ) {     // 验证输入...     if( business.util.Validation.isValidEmail(email) ) {         // 存储输入...         try {             business.db.MailingList.AddEmail(email);         } catch (Exception e) {             error = "Error adding email address to system.  " + e;         }         if( error.length()==0 ) { %>             // 重定向到欢迎页...             <jsp:forward page="welcome.html"/> <%         }     } else {         // 设置错误消息并重新显示网页         error = email + " is not a valid email address, please try again.";     } } else {     email = ""; } %> <html> <head> <title>Join Mailing List</title> </head> <body> <font color=red><%=error%></font><br> <h3>Enter your email to join the group</h3> <form action="join.jsp" name="joinForm">     <input name="email" id="email" value=<%=email%>></input>     <input type=submit value="submit"> </form> </body> </html> 


图 2. 在简单的请求和响应中,JSP 文件设置数据、控制到下一个网页的流程并创建 HTML
Simple request and response JSP

这个邮件列表 JSP 文件是一个独立的、自主完成所有任务的模块。未包含在这个 JSP 文件中的仅有代码是包含在 isValidEmail() 中的实际验证代码和将电子邮件地址存入数据库的代码。(将 isValidEmail() 方法分离到可重用的代码中似乎是当然的选择,但我曾见过直接嵌入网页中的 isValidEmail() 代码。单页方法的优点是易于理解,并且最初也易于构建。此外,对于各种图形化开发工具,入门也很容易。

join.jsp 的活动

  1. 显示打开的输入网页。
  2. 从表单参数中读取 email 的值。
  3. 验证 email 地址。
  4. 如果 email 地址有效:
    • 将该地址添加到数据库中。
    • 重定向到下一个网页。
  5. 如果 email 地址无效:
    • 设置错误消息。
    • 重新显示含有错误消息的 join.jsp

单页方法的后果

  • HTML 和 Java 强耦合在一起
    JSP 文件的编写者必须既是网页设计者,又是 Java 开发者。其结果通常要么是很糟的 Java 代码,要么是难看的网页,有时甚至 Java 代码和网页都很糟。
  • Java 和 JavaScript 的不足
    随着网页逐渐变大,很容易想到实现一些 JavaScript。当网页中出现 JavaScript 时,这种脚本就可能与 Java 代码产生混淆。可能产生混淆的一个例子是使用客户端的 JavaScript 来验证 email 域。
  • 内嵌的流程逻辑
    要理解应用程序的整个流程,您必须浏览所有网页。试想一下拥有 100 个网页的网站的错综复杂的逻辑。
  • 调试困难
    除了很糟的外观之外,HTML 标记、Java 代码和 JavaScript 代码都集中在一个网页中还使调试变得相当困难。
  • 强耦合
    更改业务逻辑或数据可能牵涉相关的每个网页。
  • 美学
    在很大的网页中,这编码样式看起来杂乱无章。我过去进行 Microsoft ASP 开发时,我经常看到有 1000 行的网页。即使有彩色语法显示,阅读和理解这些代码仍然比较困难。




回页首


请别在我的 HTML 中加入太多的 Java 代码

在清单 1 中,不是 Java 代码中有大量的 HTML,而是在 HTML 文件中有大量的 Java 代码。从这个观点来看,除了允许网页设计人员编写 Java 代码之外,我实际上没做什么。但是,我们并不是一无所有;在 JSP 1.1 中,我们获得一种称为“标记”的新特性。

JSP 标记只是将代码从 JSP 文件中抽取出来的一种方式。有人将 JSP 标记看作是 JSP 文件的宏,其中用于这个标记的代码包含在 servlet 中。(宏的观点在很大程度上是正确的。)出于同样的原因,我不希望在 Java 代码中看到 HTML 标记,我也不希望在 JSP 文件中看到 Java 代码。JSP 技术的整个出发点就是允许网页设计人员创建 servlet,而不必纠缠于 Java 代码。标记允许 Java 程序员将 Java 代码伪装成 HTML 来扩展 JSP 文件。图 3 显示了从 JSP 网页中抽取代码并将它们放入 JSP 标记中的一般概念。


图 3. JSP 标记
JSP tag breakdown

清单 2 是用来说明 Struts 标记的功能的一个例子。在清单 2 中,正常的 HTML <form> 标记被用 Struts <form:form> 标记替换。清单 3 显示了浏览器接收到的结果 HTML。浏览器获得 HTML <form> 标记,但带有附加代码,如 JavaScript。附加的 JavaScript 激活 email 地址域。服务器端的 <form:form> 标记代码创建适当的 HTML,并使网页设计人员不再接触 JavaScript。


清单 2. Struts 的 form 标记
<form:form action="join.do" focus="email" >     <form:text   property="email" size="30" maxlength="30"/>     <form:submit property="submit" value="Submit"/> </form:form> 



清单 3. 发送给浏览器的结果 HTML
<form name="joinForm" method="POST" action="join.do;jsessionid=ndj71hjo01">     <input type="text" name="email" maxlength="30" size="30" value="">     <input type="submit" name="submit" value="Submit"> </form> <script language="JavaScript"> <!--     document.joinForm.email.focus() // --> </script> 

有关 JSP 标记的注意事项:

  • JSP 标记需要一个运行 JSP 1.1 或更高版本的容器。
  • JSP 标记在服务器上运行,而不像 HTML 标记那样由客户机解释。
  • JSP 标记提供了适当的代码重用机制。
  • 可以使用一种称为 include 的 JSP 机制将 HTML 和 JavaScript 添加到网页中。但是,开发人员常常会创建巨大的 JavaScript 库文件,这些库文件被包含在 JSP 文件中。结果返回给客户机的 HTML 网页要比必需的 HMTL 网页大得多。 include 的正确用法是仅将它用于生成诸如页眉和页脚这类内容的 HTML 代码段。
  • 通过抽取出 Java 代码,JSP 标记使开发角色更加专业化。




回页首


模型-视图-控制器 (MVC)

JSP 标记只解决了部分问题。我们还得处理验证、流程控制和更新应用程序的状态等问题。这正是 MVC 发挥作用的地方。MVC 通过将问题分为三个类别来帮助解决单一模块方法所遇到的某些问题:

  • Model(模型)
    模型包含应用程序的核心功能。模型封装了应用程序的状态。有时它包含的唯一功能就是状态。它对视图或控制器一无所知。
  • View(视图)
    视图提供模型的表示。它是应用程序的 外观。视图可以访问模型的读方法,但不能访问写方法。此外,它对控制器一无所知。当更改模型时,视图应得到通知。
  • Controller(控制器)
    控制器对用户的输入作出反应。它创建并设置模型。




回页首


MVC Model 2

Web 向软件开发人员提出了一些特有的挑战,最明显的就是客户机和服务器的无状态连接。这种无状态行为使得模型很难将更改通知视图。在 Web 上,为了发现对应用程序状态的修改,浏览器必须重新查询服务器。

另一个重大变化是实现视图所用的技术与实现模型或控制器的技术不同。当然,我们可以使用 Java(或者 PERL、C/C++ 或别的语言)代码生成 HTML。这种方法有几个缺点:

  • Java 程序员应该开发服务,而不是 HTML。
  • 更改布局时需要更改代码。
  • 服务的用户应该能够创建网页来满足它们的特定需要。
  • 网页设计人员不能直接参与网页开发。
  • 嵌在代码中的 HTML 很难看。

对于 Web,需要修改标准的 MVC 形式。图 4 显示了 MVC 的 Web 改写版,通常也称为 MVC Model 2 或 MVC 2。


图 4. MVC Model 2
MVC Model 2




回页首


Struts,MVC 2 的一种实现

Struts 是一组相互协作的类、servlet 和 JSP 标记,它们组成一个可重用的 MVC 2 设计。这个定义表示 Struts 是一个框架,而不是一个库,但 Struts 也包含了丰富的标记库和独立于该框架工作的实用程序类。图 5 显示了 Struts 的一个概览。


图 5. Struts 概览
Struts overview

Struts 概览

  • Client browser(客户浏览器)
    来自客户浏览器的每个 HTTP 请求创建一个事件。Web 容器将用一个 HTTP 响应作出响应。
  • Controller(控制器)
    控制器接收来自浏览器的请求,并决定将这个请求发往何处。就 Struts 而言,控制器是以 servlet 实现的一个命令设计模式。 struts-config.xml 文件配置控制器。
  • 业务逻辑
    业务逻辑更新模型的状态,并帮助控制应用程序的流程。就 Struts 而言,这是通过作为实际业务逻辑“瘦”包装的 Action 类完成的。
  • Model(模型)的状态
    模型表示应用程序的状态。业务对象更新应用程序的状态。ActionForm bean 在会话级或请求级表示模型的状态,而不是在持久级。JSP 文件使用 JSP 标记读取来自 ActionForm bean 的信息。
  • View(视图)
    视图就是一个 JSP 文件。其中没有流程逻辑,没有业务逻辑,也没有模型信息 -- 只有标记。标记是使 Struts 有别于其他框架(如 Velocity)的因素之一。




回页首


详细分析 Struts

图 6 显示的是 org.apache.struts.action 包的一个最简 UML 图。图 6 显示了 ActionServlet (Controller)、 ActionForm (Form State) 和 Action (Model Wrapper) 之间的最简关系。


图 6. Command (ActionServlet) 与 Model (Action & ActionForm) 之间的关系的 UML 图
Relationship of ActionServlet to Action and ActionForm

ActionServlet 类

您还记得函数映射的日子吗?在那时,您会将某些输入事件映射到一个函数指针上。如果您对此比较熟悉,您会将配置信息放入一个文件,并在运行时加载这个文件。函数指针数组曾经是用 C 语言进行结构化编程的很好方法。

现在好多了,我们有了 Java 技术、XML、J2EE,等等。Struts 的控制器是将事件(事件通常是 HTTP post)映射到类的一个 servlet。正如您所料 -- 控制器使用配置文件以使您不必对这些值进行硬编码。时代变了,但方法依旧。

ActionServlet 是该 MVC 实现的 Command 部分,它是这一框架的核心。 ActionServlet (Command) 创建并使用 ActionActionFormActionForward 。如前所述, struts-config.xml 文件配置该 Command。在创建 Web 项目时,您将扩展 ActionActionForm 来解决特定的问题。文件 struts-config.xml 指示 ActionServlet 如何使用这些扩展的类。这种方法有几个优点:

  • 应用程序的整个逻辑流程都存储在一个分层的文本文件中。这使得人们更容易查看和理解它,尤其是对于大型应用程序而言。
  • 网页设计人员不必费力地阅读 Java 代码来理解应用程序的流程。
  • Java 开发人员也不必在更改流程以后重新编译代码。

可以通过扩展 ActionServlet 来添加 Command 功能。

ActionForm 类

ActionForm 维护 Web 应用程序的会话状态。 ActionForm 是一个抽象类,必须为每个输入表单模型创建该类的子类。当我说 输入表单模型 时,是指 ActionForm 表示的是由 HTML 表单设置或更新的一般意义上的数据。例如,您可能有一个由 HTML 表单设置的 UserActionForm 。Struts 框架将执行以下操作:

  • 检查 UserActionForm 是否存在;如果不存在,它将创建该类的一个实例。
  • Struts 将使用 HttpServletRequest 中相应的域设置 UserActionForm 的状态。没有太多讨厌的 request.getParameter() 调用。例如,Struts 框架将从请求流中提取 fname ,并调用 UserActionForm.setFname()
  • Struts 框架在将 UserActionForm 传递给业务包装 UserAction 之前将更新它的状态。
  • 在将它传递给 Action 类之前,Struts 还会对 UserActionForm 调用 validation() 方法进行表单状态验证。 注: 这并不总是明智之举。别的网页或业务可能使用 UserActionForm ,在这些地方,验证可能有所不同。在 UserAction 类中进行状态验证可能更好。
  • 可在会话级维护 UserActionForm

注:

  • struts-config.xml 文件控制 HTML 表单请求与 ActionForm 之间的映射关系。
  • 可将多个请求映射到 UserActionForm
  • UserActionForm 可跨多页进行映射,以执行诸如向导之类的操作。

Action 类

Action 类是业务逻辑的一个包装。 Action 类的用途是将 HttpServletRequest 转换为业务逻辑。要使用 Action ,请创建它的子类并覆盖 process() 方法。

ActionServlet (Command) 使用 perform() 方法将参数化的类传递给 ActionForm 。仍然没有太多讨厌的 request.getParameter() 调用。当事件进展到这一步时,输入表单数据(或 HTML 表单数据)已被从请求流中提取出来并转移到 ActionForm 类中。

注:扩展 Action 类时请注意简洁。 Action 类应该控制应用程序的流程,而不应该控制应用程序的逻辑。通过将业务逻辑放在单独的包或 EJB 中,我们就可以提供更大的灵活性和可重用性。

考虑 Action 类的另一种方式是 Adapter 设计模式。 Action 的用途是“将类的接口转换为客户机所需的另一个接口。Adapter 使类能够协同工作,如果没有 Adapter,则这些类会因为不兼容的接口而无法协同工作。”(摘自 Gof 所著的 Design Patterns - Elements of Reusable OO Software )。本例中的客户机是 ActionServlet ,它对我们的具体业务类接口一无所知。因此,Struts 提供了它能够理解的一个业务接口,即 Action 。通过扩展 Action ,我们使得我们的业务接口与 Struts 业务接口保持兼容。(一个有趣的发现是, Action 是类而不是接口)。 Action 开始为一个接口,后来却变成了一个类。真是金无足赤。)

Error 类

UML 图(图 6)还包括 ActionErrorActionErrorsActionError 封装了单个错误消息。 ActionErrorsActionError 类的容器,View 可以使用标记访问这些类。 ActionError 是 Struts 保持错误列表的方式。


图 7. Command (ActionServlet) 与 Model (Action) 之间的关系的 UML 图
Relationship of ActionServlet to Action

ActionMapping 类

输入事件通常是在 HTTP 请求表单中发生的,servlet 容器将 HTTP 请求转换为 HttpServletRequest 。控制器查看输入事件并将请求分派给某个 Action 类。 struts-config.xml 确定 Controller 调用哪个 Action 类。 struts-config.xml 配置信息被转换为一组 ActionMapping ,而后者又被放入 ActionMappings 容器中。(您可能尚未注意到这一点,以 s结尾的类就是容器)

ActionMapping 包含有关特定事件如何映射到特定 Action 的信息。 ActionServlet (Command) 通过 perform() 方法将 ActionMapping 传递给 Action 类。这样就使 Action 可访问用于控制流程的信息。

ActionMappings

ActionMappingsActionMapping 对象的一个集合。





回页首


再访邮件列表样例

下面我们看一下 Struts 是如何解决困扰 join.jsp 的这些问题的。改写后的方案由两个项目组成。第一个项目包含应用程序的逻辑部分,这个应用程序是独立于 Web 应用程序的。这个独立层可能是用 EJB 技术实现的公共服务层。为了便于说明,我使用 Ant 构建进程创建了一个称为 business 的包。有几个原因促使我们使用独立的业务层:

  • 划分责任
    单独的包使管理人员能够在开发小组内委派责任。这也有助于提高开发人员的责任心。
  • 通用件
    我们设想开发人员将这个包看作一个商业软件。将它放在另外的包中使它更像通用件。这个包可能是通用件,也可能是由组织内部的另一个小组开发的。
  • 避免不必要的构建和单元测试。
    分开的构建进程有助于避免不必要的构建和单元测试。
  • 使用接口开发
    在进行开发和避免不必要的耦合时,它有助于从接口的观点来思考问题。这是极重要的一个方面。当开发您自己的业务包时,这些业务类不应该关心到底是 Web 应用程序执行调用,还是独立应用程序执行调用。因此,应该避免在业务逻辑层使用对 servlet API 或 Struts API 调用的任何引用。
  • 稳定性
    并不是每个组织都每天、每周甚至每月进行检修。因此,在进行开发时,稳定的接口点是重要的。不能因为业务包处于变迁阶段就认为 Web 项目也应该处于变迁阶段。

业务构建注释

我用 Ant 构建项目,并用 JUnit 运行单元测试。business.zip 包含构建业务项目所需的一切,当然 Ant 和 JUnit 除外。这个包脚本将构建类,运行单元测试,创建 Java 文档和 jar 文件,最后将所有这些内容压缩到一个 zip 文件中发送给客户。只要对 build.xml 作一些修改,您就可以将它部署到其他平台上。 Business.jar 位于 Web 的下载部分,因此,您并非必须下载并构建这个业务包。

Web 项目

第二个项目是用 Struts 开发的一个 Web 应用程序。您将需要一个符合 JSP 1.1 和 Servlet 2.2 规范的容器。最快的入门方法是下载并安装 Tomcat 3.2(请参阅 参考资源 )。直到有 Struts 的 1.0 发行版之前,我建议您从 Jakarta 项目获得最新的版本(请参阅 参考资源 )。这对我来说是个大问题,我不能确保我的 Web 项目样例能与您下载的 Struts 一起工作。Struts 仍在不断变化,所以我不得不经常更新我的项目。在本项目中,我使用的是 jakarta-struts-20010105.zip。图 8 显示了此 Web 项目的结构。如果您已安装了 Ant,则运行这个版本将创建一个称为 joinStruts.war 的 war 文件,您随时可以部署这个文件。


图 8. Web 项目的结构
Web project layout

清单 4 显示了转换后的 JSP 文件,称为 joinMVC.jsp 。这个文件从最初的 50 行变为 19 行,并且现在不含任何 Java 代码。从网页设计人员的角度来看,这是个巨大的改进。


清单 4. joinMVC.jsp -- 再访简单的 JSP
<%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %> <%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %> <html> <head> <title><struts:message key="join.title"/></title> </head> <body bgcolor="white"> <form:errors/> <h3>Enter your email to join the group</h3> <form:form action="join.do" focus="email" >     <form:text   property="email" size="30" maxlength="30"/>     <form:submit property="submit" value="Submit"/> </form:form> </body> </html> 

网页的变化

下面是使用 Struts 标记库之后所发生变化的列表:

  • Import
    <%@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %> 

    用于 Java 代码的 <%@page import? 已被替换为用于 Struts 标记库的 <%@ taglib uri?
  • 文本
    <struts:message key="join.title"/> 

    资源属性文件包含 join.title 的文本。在本例中,ApplicationResources 属性文件包含这个名值对。这使字符串更易于查看和国际化。
  • 错误
    <form:errors/> 

    ActionServletActionForm 构建要显示的错误消息。这些错误消息也可以包含在属性文件中。ApplicationResources 也提供了一种格式化错误的方法,即设置 error.headererror.footer
  • HTML 表单
    <form:form action="join.do" focus="email" > 

    • JSP <form> 标记和属性替代了 HTML <form> 标记和属性。 <form action="join.jsp" name="join"> 已更改为 <form:form action="join.do" focus="email" >
    • HTML <input> 标记已替换为 <form:text/>
    • HTML <submit> 标记已替换为 <form:submit/>

模型 -- 会话状态

JoinForm 扩展了 ActionForm 并包含表单数据。本例中的表单数据只有电子邮件地址。我已为电子邮件地址添加了一个写方法和读方法,以供框架访问。为了便于说明,我重写了 validate() 方法,并使用了 Struts 的跟踪功能。Struts 将创建 JoinForm 并设置状态信息。

模型 -- 业务逻辑

如前所述, Action 是控制器和实际业务对象之间的接口。 JoinAction 包装了对 business.jar 的调用,这些调用最初在 join.jsp 文件中。 JoinActionperform() 方法在清单 5 中列表。


清单 5. - JoinAction.perform()
public ActionForward perform(ActionMapping mapping,                              ActionForm form,                              HttpServletRequest request,                              HttpServletResponse response)                              throws IOException, ServletException {     // 抽取我们将会用到的属性和参数     JoinForm joinForm = (JoinForm) form;     String email = joinForm.getEmail();     ActionErrors errors = new ActionErrors();     // 存储输入....     try {         business.db.MailingList.AddEmail(email);     } catch (Exception e) {         // 记录日志,打印栈         // 将错误回显给用户         errors.add("email",new ActionError("error.mailing.db.add"));     }     // 如需任何消息,请将指定的错误消息键保存到     //  HTTP 请求中,以供 <struts:errors> 标记使用。     if (!errors.empty()) {         saveErrors(request, errors);         // 返回到初始表单         return (new ActionForward(mapping.getInput()));     }     // 将控制权转交给 Action.xml 中指定的 'success' URI     return (mapping.findForward("success")); } 

注: perform() 返回一个称为 ActionForward 的类,该类通知控制器下一步该执行什么操作。在本例中,我使用从控制器传入的映射来决定下一步的操作。

控制器

我已修改了 JSP 文件,并创建了两个新类:一个类用来包含表单数据,一个类用来调用业务包。最后,我通过修改配置文件 struts-config.xml 将它们整合起来。清单 6 显示了我添加的 action 元素,这个元素用来控制 joinMVC.jsp 的流程。


清单 6. Action 配置
<action  path="/join"          name="joinForm"          type="web.mailinglist.JoinAction"         scope="request"         input="/joinMVC.jsp"      validate="true">     <forward  name="success"  path="/welcome.html"/> </action> 

action 元素描述了从请求路径到相应的 Action 类的映射,应该用这些类来处理来自这个路径的请求。每个请求类型都应该有相应的 action 元素,用来描述如何处理该请求。对于 join 请求:

  1. joinForm 用来容纳表单数据。
  2. 因为 validate 被标记为 true,所以 joinForm 将试图进行自我验证。
  3. web.mailinglist.JoinAction 是用来处理对这个映射的请求的 action 类。
  4. 如果一切顺利,该请求将转到 welcome.jsp
  5. 如果出现业务逻辑故障,流程将返回到 joinMVC.jsp ,这是最初发出请求的网页。为什么会这样呢?在清单 6 的 action 元素中,有一个称为 input 的属性,其值为 "/joinMVC.jsp" 。在我的 JoinAction.perform() (如清单 5 所示)中,如果业务逻辑失败, perform() 就返回一个 ActionForward ,并以 mapping.getInput() 作为参数。本例中的 getInput()"/joinMVC.jsp" 。如果业务逻辑失败,它将返回到 joinMVC.jsp ,这是最初发出请求的网页。




回页首


使用 Struts 前后的比较

正如我们在图 9 中所看到的那样,复杂性和层都有显著增加。不再存在从 JSP 文件到 Service 层的直接调用。


图 9. 使用 Struts 前后的比较
Before and after Struts

Struts 的优点

  • JSP 标记机制的使用
    标记特性从 JSP 文件获得可重用代码和抽象 Java 代码。这个特性能很好地集成到基于 JSP 的开发工具中,这些工具允许用标记编写代码。
  • 标记库
    为什么要另发明一种轮子,或标记库呢?如果您在库中找不到您所要的标记,那就自己定义吧。此外,如果您正在学习 JSP 标记技术,则 Struts 为您提供了一个起点。
  • 开放源码
    您可以获得开放源码的全部优点,比如可以查看代码并让使用库的每个人检查代码。许多人都可以进行很好的代码检查。
  • MVC 实现样例
    如果您希望创建您自己的 MVC 实现,则 Struts 可增加您的见识。
  • 管理问题空间
    分治是解决问题并使问题可管理的极好方法。当然,这是一把双刃剑。问题越来越复杂,并且需要越来越多的管理。

Struts 的缺点

  • 仍处于发展初期
    Struts 开发仍处于初级阶段。他们正在向着发行版本 1.0 而努力,但与任何 1.0 版本一样,它不可能尽善尽美。
  • 仍在变化中
    这个框架仍在快速变化。Struts 1.0 与 Struts 0.5 相比变化极大。为了避免使用不赞成使用的方法,您可能隔一天就需要下载最新的 Struts。在过去的 6 个月中,我目睹 Struts 库从 90K 增大到 270K 以上。由于 Struts 中的变化,我不得不数次修改我的示例,但我不保证我的示例能与您下载的 Struts 协同工作。
  • 正确的抽象级别
    Struts 是否提供了正确的抽象级别?对于网页设计人员而言,什么是正确的抽象级别呢?这是一个用 $64K 的文字才能解释清楚的问题。在开发网页的过程中,我们是否应该让网页设计人员访问 Java 代码?某些框架(如 Velocity)说不应该,但它提供了另一种 Web 开发语言让我们学习。在 UI 开发中限制访问 Java 有一定的合理性。最重要的是,如果让网页设计人员使用一点 Java,他将使用大量的 Java。在 Microsoft ASP 的开发中,我总是看到这样的情况。在 ASP 开发中,您应该创建 COM 对象,然后编写少量的 ASP 脚本将这些 COM 对象联系起来。但是,ASP 开发人员会疯狂地使用 ASP 脚本。我会听到这样的话,“既然我可以用 VBScript 直接编写 COM 对象,为什么还要等 COM 开发人员来创建它呢?”通过使用标记库,Struts 有助于限制 JSP 文件中所需的 Java 代码的数量。Logic Tag 就是这样的一种库,它对有条件地生成输出进行管理,但这并不能阻止 UI 开发人员对 Java 代码的狂热。无论您决定使用哪种类型的框架,您都应该了解您要在其中部署和维护该框架的环境。当然,这项任务真是说起来容易做起来难。
  • 有限的适用范围
    Struts 是一种基于 Web 的 MVC 解决方案,所以必须用 HTML、JSP 文件和 servlet 来实现它。
  • J2EE 应用程序支持
    Struts 需要支持 JSP 1.1 和 Servlet 2.2 规范的 servlet 容器。仅凭这一点远不能解决您的全部安装问题,除非使用 Tomcat 3.2。我用 Netscape iPlanet 6.0 安装这个库时遇到一大堆问题,按理说它是第一种符合 J2EE 的应用程序服务器。我建议您在遇到问题时访问 Struts 用户邮件列表的归档资料(请参阅 参考资源)。
  • 复杂性
    在将问题分为几个部分的同时也引入了复杂性。毫无疑问,要理解 Struts 必须接受一定的培训。随着变化的不断加入,这有时会令人很沮丧。欢迎访问本网站。
  • 在何处...
    我还能指出其他问题,例如,控制器的客户端验证、可适用工作流程和动态策略模式在什么地方?但是,目前这太容易成为吹毛求疵的问题,有些问题是无关紧要的,或者说应该对 1.0 发行版提这些问题。随着 Struts 小组的不断努力,到您阅读本文时 Struts 说不定已经有了这些功能,或者它很快就会具有这些功能。




回页首


Struts 的前景

在这个软件开发的新时代,一切都变得很快。在不到 5 年的时间内,我已经目睹了从 cgi/perl 到 ISAPI/NSAPI、再到使用 VB 的 ASP、一直到现在的 Java 和 J2EE 的变迁。Sun 正在尽力将新的变化反映到 JSP/servlet 体系结构中,正如他们对 Java 语言和 API 所作的更改一样。您可以从 Sun 的网站获得新的 JSP 1.2 和 Servlet 2.3 规范的草案。此外,一个标准 JSP 标记库即将出现;有关这些规范和标记库的链接,请参阅 参考资源





回页首


最后的注释

Struts 使用标记和 MVC 解决了某些重大问题。这个方法有助于提高代码的可重用性和灵活性。通过将问题划分为更小的组件,当技术空间或问题空间中出现变化时,您就有更多的机会重用代码。此外,Struts 使网页设计人员和 Java 开发人员能将精力集中于自己最擅长的方面。但是,在强健性增强的同时,也意味着复杂性的增加。Struts 比简单的单个 JSP 网页要复杂得多,但对于更大的系统而言,Struts 实际上有助于管理复杂性。另外,我并不想编写自己的 MVC 实现,而只想了解一个这样的实现。不管您是否会使用 Struts,回顾这个 Struts 框架(对不起,应该是库)都会使您对 JSP 文件和 servlet 的特性、以及如何将它们组合起来用于您的下一个 Web 项目有更好的了解。正像翼间支柱是机翼结构中不可缺少的一部分一样,Strut 也可能成为您下一个 Web 项目的不可缺少的一部分。



参考资料



关于作者

Malcolm G. Davis 住在阿拉巴马州伯明翰市,他在自己的咨询公司当总裁。他自称是一名 Java 传道者。他在宣传 Java 的优点的闲暇之余,他会去长跑,或者与自己的孩子一起玩。可以通过 malcolm@nuearth.com 与 Malcolm 联系。