2005年3月4日星期五

《ASD》设计模式:Observer

Observer模式稍稍有点复杂,但是由于他的作用如此强大,所以几乎在所有的带有分层概念的系统中都必须使用。
带有GUI的软件几乎都有分层的概念,界面是一层,逻辑实现是一层。所以他们也就成了最常见的Observer模式的例子。
不过Observer模式的用处要比单纯的GUI要宽广很多。Observer的应用环境是,有上下两层模块,下层模块的数据会自发变化,上层模块必须响应这样的变化,但是上层模块不知道下层模块会在什么时候变化。这种情况下就应该使用Observer模式,上层模块让下层模块知道自己的存在,然后在下层模块在变化的时候通知上层模块。
Observer模式的另一个比较有趣的别名是Hollywood模式,因为这个模式可以被描述为“Don't call me, I'll call you.”。
由于Observer如此的常用,所以在实际的使用过程中,这已经是一个烂熟于心的模式。《ASD》一书在讲述这个模式的时候,也没有多少新意,但是还让我有一些点滴的感想:

- Observer模式是典型的由DIP原则驱动的模式。无论是上层数据的变化还是界面的显示都是具体类。具体类应该是不稳定的,不能被依靠。所以必须抽象出接口,就是下层的Subject接口和上层的Observer接口。Subject接口依赖Observer接口。

- 根据单一职责原则(SRP)和接口分离原则(ISP),Subject应该只是处理register和notify的任务,而和具体逻辑无关。这在使用拉模式时尤其需要注意。

- Observer模式有推模式和拉模式两种方法。推模式中,由Subject把数据直接告诉Observer。在拉模式种,Subject只是告诉Observer有事情在变化,然后由Observer来查询是什么数据变化了。究竟使用何种模式应该视具体应用而定。然而常常是两个模式的混合运用。

- 在使用拉模式的时候,Observer要向下层询问获取数据。然而数据属于具体的业务逻辑,和Observer模式的框架无关。因此这个接口不应该被包含在Subject接口中,而需要设立一个单独的业务接口。也就是说,在这种情况下,下层模块要继承两个接口,Subject接口和自己的业务逻辑相关的接口。(如果不这么作,将会形成依赖环)

- 如果把推模式和拉模式混合使用,即是,Subject告诉Observer一个消息,提示是何种变化。Observer判断是否要查询更具体的数据,或者如何查询。这就是消息驱动系统了。

- 另外一种变化是,Observer在注册的时候,就表明自己对何种消息感兴趣。Subject在事件发生的时候,只是通知感兴趣的Observer。

2005年3月3日星期四

《ASD》设计模式:Composite

我对于Comosite模式有种特殊的感情,因为这是我第一个理解了的模式。之前看《设计模式》一直未能理解模式的意义,直到看到Comopiste,才觉得豁然开朗。之后再看其它模式,也觉得能够理解模式背后的意图了。

Composite模式其实是一种非常特别的模式,因为他所关注的是结构,而较少关注行为。这与大部分的设计模式是有所不同的。
可是,Composite模式的结构是非常精巧的,甚至可以称之为美丽动人。
元素合在一起组成了结构。结构可以和零散的元素或者别的结构再次组合,形成新的结构。这样的组合可以无穷尽地延续下去。
常常,我们需要的是最上层的整体。
Composite模式让我们可以在运行时期,用组合的方式来建造这样的整体。
Composite模式较少被误用。因为她的应用总是在特别的面向数据结构的上下文环境。而且也没有多少别的方法可以顶替Composite的作用。
Composite模式不太关注行为,即如何使用这个巨大组合结构中的元素。她本身只提供了很简单的深度优先的遍历方法。
如果有更高的行为上的要求,就要借助于另外两个模式:iterator和vistor。

迁徙的野鸭

今天早上去上班的时候,有两只类似野鸭的鸟从我头顶飞过。莫非春天来了,又到了候鸟们迁徙的时候了?
突然很想再看一次那部美轮美奂的电影《迁徙的鸟》。可惜身边没有碟片。而且这电影要在大屏幕上看才舒服。
《迁徙的鸟》中有大量的和候鸟们同步飞行的镜头,观看的时候,感觉自己也在和鸟儿们一同飞翔。当镜头跟着鸟群,在挣脱地面束缚的那一刹那,心中有种感动在暗涌。
候鸟的迁徙是非常伟大的。套用电影中的台词,迁徙的鸟是一个关于承诺的故事。
没有电影看,就只能贴张海报了。

See The Future. Make History.

今明两天,在Redmond有微软一年一届的TechFest。微软在全世界的六个研究院(Redmond,湾区,硅谷,剑桥,北京,印度)都会在这个TechFest上,展示自己一年来的成果。See the future. Makes history就是本届TechFest的口号。
TechFest在三个大会议室中,布置了很多摊位,每个摊位上都有一个技术展示。另外还有两个大会议室,用来作一小时一个的报告。
我今天去的稍晚了一点,到场的时候已经快要4:30PM了。没有去听报告,直接去展厅看技术展示。有很多展示都非常让人兴奋,花了一个半小时,只是马马虎虎地看完了一个展厅。剩下的两个展厅就已经关门了。
只能暗下决心,明天一定要早点去。
我拿不准今天看到的东西中,有多少是可以公开谈论的。所以只好不谈具体细节,只说说大致内容。
在今天这个展厅中,展示的技术,主要集中在系统与网络、软件工程、数据库、P2P方面。身为程序员,当然是软件工程方面的技术最有切身关系。有几个项目,和单元测试、源码数据挖掘、编程框架相关的,让我觉得特别的兴奋。真的是非常希望能够快点用上他们的成果。

2005年3月2日星期三

相声瓦舍

我用eMule下载了一些台湾相声瓦舍表演的相声段落。听了之后,觉得非常过瘾。
相声瓦舍中,最重要的两个表演者当属冯翊君和宋少卿二人。感觉上这两人的语言基本功依然不如大陆的一流相声演员,再表演报菜名这样的传统段子的时候,虽然还算精彩,但是就远不如大陆相声演员的神乎其技。
可是谁喜欢看一个人站在台上口沫四溅的念绕口令?

相声瓦舍最让人觉得过瘾的是他们的讽刺态度。讽刺时政,也讽刺不良的国民性。例如《相声说跨鬼子》系列,听来实在过瘾。
然而有些段子,虽然没有太强烈的讽刺意味,例如《战国厕》,但是想像之丰富,也是大陆的相声中所见不到的。
在创作的时候,束手束脚,这也不能,那也不能,久而久之,连正常的想像力也都没有了。大陆的相声创作大概就是如此。

之前,听过一个一米线的理论。
大意是说,有一个限制在那里,谁都知道不能跨过那根线,否则就很糟糕了。
可是这样是不够的。编辑还很担心,自己会失手放过什么过界的东西吗。所以编辑会在那个限制之前,退出一米再划根线。
然后是作者。他们会在编辑的那根线之前,再退出一米,再划一根线。
可实际上,并不只有这三根线。
因为所有的人都不确定自己的那根线是否划对了。看到别人的线好像更远一点,自己也就再退一点。
于是你退一米,我退一米。那根线就越退越远了。
真正的问题不是在于那根线在哪里,而是在于有那么一根线,人就失去了一种自由的能力。
这就是所谓的精神阉割。

所以,听听相声瓦舍,听听没有被阉割过的声音,真的很过瘾啊。

2005年2月28日星期一

Hike of Rattlesnake Mountain

今天和几个中国同事去爬Rattlesnkae Mountain。似乎这是我去年冬天以来的第一次hiking。

Seatllte附近多山,因此也有颇多的登山爱好者。连带着,也就有了很多供hiking用的trail。随便一个小山丘或者湖边,都有一两条trail。

在国内,北京附近爬山,常常是要么没有路,要么路边全是卖东西的。

而在这里,风格却很不同。到处有专门供人远足用的小路,但是没有什么人卖东西。似乎也没有什么人来维护。小路两边没有垃圾桶,也不会有人把垃圾扔在路边。感觉这里的大部分地方都已经被开发过了,但是又保持着一种很自然的面貌。

对于爱好爬山的人来说,这里确实是一个非常惬意的所在。

Rattlesnkae Mountain应该算是比较有名的爬山去处。今天爬上的一路上,见到了不少人。(相对于这里别的地方而言,和北京香山的人海是完全不能比的了)。很多人都带着狗。也有几个人背着小孩。

这次hiking的路程很短,只有2 miles,合3.2公里。不过等上山峰以后,视野到也是非常开阔。

最遗憾的是,我虽然带了DC上山,但是居然忘了带存储卡。所以今天这里附带的照片都是我的朋友Jun拍的。Jun的照片拍得非常漂亮,大家可以去他的blog看看。



照片链接:Rattlesnake Mountain

2005年2月27日星期日

出游(玩具商店,华盛顿大学)

春暖花开的周末,照例出去兜风。


中午先去了Bellevue Square,看了看朋友推荐的几个特色商店,Sharper Image和Discovery Chanel Shop。这几个商店都是卖一些特别的“玩具”,例如把时间显示投影到墙上的钟,电动的DVD架,在地毯上自动游弋的吸尘器。Discovery卖的东西相对要低龄化一些,比如用来侍养蚂蚁的模拟生态环境,能显示当前天空星座的灯。
与其说是卖“玩具”,不如说是卖idea的商店。很多东西都非常对我的口味。可是论到价格,于国人而言,却已经不能当作玩具来看待了。


这些天不少地方的樱花都开了。所以我们下午去了华盛顿大学,希望能看到盛开的樱花。不过可惜的,华大里的大部分樱花树还只是含苞待放的状态,算是有点遗憾了。



对于华大,我没有什么好说的。梅贻琦先生说,大学者,乃有大师之谓也,非大楼之谓也。
我只是看了看华大的大楼,当然是什么也说不出来了。

2005年2月26日星期六

《ASD》设计模式:Factory - 兼谈模式的滥用

operator new是个很特别的命令,只要一出现,就会破坏DIP(依赖倒置原则)和OCP(开放封闭原则),然而她又是不能避免的命令。
解决办法就是使用Factory模式,把new命令与使用者隔离开来。
然而依然需要一个地方来创建Facotry类的具体实例,不过这个工作可以放在应用程序的初始化部分来作,与其它应用还是隔离开来的。
关于Factory应该不用多写什么了。对于一个面向对象程序员来说,这可能是最常见的模式了。
不过可以谈谈什么时候该用Factory模式。

原则上说,当创建一个可能会变化的具体对象时,就应该(必须)要使用Factory模式。
然而,什么对象是会变化呢?
传统的设计方法是在最初的设计时就考虑这个问题。
可是极限编程的思想略有不同。

极限编程则认为,第一,在项目之初是很难预料哪些类是会变化的,所以不应该预先考虑这些变化。
说实话,对于设计工程师来说,要接受这个观点还真的有点痛苦。虽然我知道她说的是真的。
如果,软件不需要变化,那么面向对象的思想就失去了大半的意义。因此工程师们一定要让自己的作品能够灵活地响应变化,这也就是OCP的原则。
然而,当运用了大堆的strategy、template、factory等等模式,建造出一个叹为观止的系统后,只等着需求改变,这个系统就能体现出OCP的好处。这时就象是搭了一个完美的陷阱,只等着猎物经过。
可惜的是,猎物却常常并不从设置陷阱的地方出现。需求的改变总是出乎设计者的预想。那个陷阱成了一个完美的装饰品。
我写过很多这样的装饰品。他们唯一的用处就是给后来者作为学习的例子。

那么该在何时使用这些模式来让程序变得坚固而灵活可以承受需求的改变呢?
极限编程认为,第二,发生过变化的地方趋向于再次变化。套用一句老话,“可以跌倒,但是不可以在同一个地方跌倒”
就软件设计而言,在最初,并不去考虑应该应对什么样的变化。只有当第一次变化出现的时候,才去更改设计,让程序对这种变化能够遵守OCP的原则。并且,这种改动后的设计,应该能够应对今后出现的所有同类变化。
我想,对于设计工程师,这种观念应该是可以接受的。

设计模式的初学者,就好像拾到了一本秘籍的孩子。艺成下山,不管遇到什么都想施展一下拳脚。这就是模式的滥用。
如何避免模式的滥用,应该多考虑一下上面所说的两条原则。

2005年2月24日星期四

《ASD》包的设计原则-兼谈极限编程

我在之前谈ASD的时候,都有意回避了开发流程的问题。然而实际上敏捷开发就是极限编程的另一个名字。
对于一个了解传统软件工程的人来说,甚至对于一个有传统项目开发经验的人来说,极限编程的观念都有点难于接受。正因为如此,我闭口不谈极限编程,只谈论设计模式。无论如何设计模式是好东西。
到了“包”的部分,极限编程的话题再也绕不开了。
极限编程中最惊世骇俗的部分大概是,反对建模,直接实现功能,然后在软件具备一定规模之后,才由下向上的设计“包”。
如果过去有人向我提出这样的观念,一定会被我B4的,但是我现在到觉得,极限编程有一定道理。至少她在规模较小的项目中是有道理的。
该如何衡量项目大小呢?这又是一个很难的问题。但是可以确定的是,大部分的项目都是小项目。

极限编程认为,在实现功能之前,先建建立全局的模型是没有意义的,这样的模型只会限制软件的开发,然后模型和实现双方互相妥协,结果模型被改得面目全非,还是离理想结果相距甚远。

反对极限编程的人认为,没有总体模型的指导,实现会缺乏大局观,变得混乱重复,难于维护。

极限编程提高维护性的主要作法就是依赖“包”。“包”并不是传统的模块的概念,而只是一个软件结构的映射,用于管理依赖和重用。
而由于测试驱动开发,软件结构是非常容易变动的,所以可以在混乱刚出现的时候,调整“包”,来恢复整个软件结构的有序。
但是如果没有总体的模型,开发人员在实现功能的时候,如何才能知道有没有可以重用的包呢?在调整软件的时候,又如何知道该调整到哪个包里去呢?
这就是说,需要有人(很多人,最好是全部开发人员)了解整个系统的情况,知道包的结构。
这也是极限编程强调结对开发(pair development)的原因之一。结对开发的要义不仅是两个人一块干活,而且还是要经常变更自己的开发伴侣,开发系统中的不同模块。这样让知识在团队中广泛传播。团队中的每个人,都对系统中的各个部分都有所认识,然后软件的灵活调整才能得以实现。

我基本上同意上诉观点。还有两个推论:
第一个推论,项目的大小取决于开发人员的能力。由上面的讨论可以看出,要实施极限编程,需要每个开发人员都了解系统的结构。但是,事实上,个人的能力有限,在有限的时间中,能够理解的系统结构也是有限的。超出了这个限制之后,极限编程大概就会暴露出越来越多的问题。所以,极限编程确实在较小的项目中比较有效,这个大小的限制即是开发人员能够理解的系统的大小。团队中开发人员平均水平越强,极限编程能够支持的系统也就越大。
推论的推论,如果是作一个个人作品,毫无疑问的应该使用极限编程。
顺便一提的是,与极限编程对应的另一种方法是软件工厂,即是由少量的精英的制定模型,大量的软件蓝领实现极细小的模块。虽然我由衷的不喜欢这个点子,但是也许这种方法更适合中国的国庆。
第二个推论,极限编程的各个部分有着密切的关系,分开来应用其中的一条两条,并非极限编程。

好了,下面来谈论包的设计原则。前面已经提到,包的主要目的是管理软件模块的依赖关系和重用。包的设计原则就是为了使这样的管理尽可能的最优化。
下面来看看这些原则。这些原则的前提是,这是一个应用极限编程的项目。即是说,项目的规模有限,并且已经有了一定规模的类,现在要用包来管理这些类。

内聚性原则:包括REP,CRP,SRP。这里主要解决的是包的粒度问题,多少类该被放进同一个包中。然而,包其实并不等于软件模块,所以包的大小在通常情况下,是远小于软件模块的,就是说,同一个模块可能被放在多个包中。
REP是重用发布等价原则,重用的粒度就是发布的粒度。即是说,一个包中的软件要么都是可重用的,要么都是不可重用的。我的理解是,实现feature时要想想,那些部分是这个feature独有的,那些部分是其它feature也可以用的。这两个部分要分入不同的包中。
CRP,共同重用原则,一个包中的所有类应该是共同重用的。如果重用了包中的一个类,那么就要重用包中的所有类。我的理解是,即使一个feature中有很多部分都是可以重用的。但如果这些部分可以单独重用,那么也要分入不同的包。
CCP,共同封闭原则,包中的所有类对于同一类性质的变化应该是共同封闭的。一个变化若对一个包产生影响,则将对该包中的所有类产生影响,而对于其它的包不造成任何影响。我的理解是,应该把对于同一个变化敏感的类尽量放入同一个包中。
用不太准确的说法来说,前两个原则的动力来自包的client,趋向于拆分包;后一个原则的动力来自包的server,趋向于聚合包。包的粒度就是在这两种力量之间的动态平衡。需要注意的是,所谓包的client和server可能和你的想像有所不同。

耦合性原则,包括无环依赖原则,稳定依赖原则,稳定抽象原则。这些原则主要用于解决包之间的依赖关系。
无环依赖原则,在包的依赖关系图中,不允许存在环。所谓包的依赖是指,如果A包中的文件依赖B包中的文件时,就是A包依赖B包。(之前在DIP原则(类的设计原则)中,已经提到了实现应该依赖于接口。)这是一个应该严格遵守的原则,只有遵守了这个原则,才能谈后两个耦合性原则。依赖关系中如果出现了环,就要解决掉环。解决环的方法有两个,第一个方法的提示是DIP原则。第二个方法是,把两个包都依赖的部分提取出来作成第三个包,让两个包都依赖于这个包。这个方法的提示是,包在开发过程中是动态变化的。
稳定依赖原则,朝着稳定的方向进行依赖。所谓稳定性,即是包的依赖关系。若是包A依赖一大堆其它的包,那么任何一个包的变化,都会引起包A的变化,包A即是不稳定的。相反,若一大堆的包依赖包B,那么包B若要变化就会引起很多其它包的变化,这么说包B很难改变,包B即是稳定的。《ASD》中描述了一个计算不稳定性的方法,称为不稳定性度量I,主要取决于依赖于包的类的数量和包中依赖于包外的类的数量,具体算法很简单,略。I是一个比值,范围是[0,1]。0时最稳定,1时最不稳定。这个I值对于类的划分有点意义,要把不变的类放入I值较小的包,把要变的类放入I值较大的包。但是I的主要意义是表现在稳定抽象原则中。
稳定抽象原则,包的抽象程度应该和其稳定程度一致。理论上,抽象类即是接口,趋向于不变,具体类即是实现,趋向于变化。《ASD》再次给出一个描述包的抽象性度量A,即是用包中抽象类的总数除以保重类的总数得到的比值。这个抽象性A的取值范围是从0到1,数值越大,抽象性越大。因此,在理想的系统中,I越大,A就应该越小;A越大,I就应该越小。若是把A和I作成二维的坐标体系,那么(0,1)到(1,0)的连线就是一根理想连线,若是一个包远离这个连线,那么这个包的设计就是有问题的。
这个让我想到,也许应该设计一个软件来自动管理包的A值和I值,自动给出统计数据。那么对于系统的设计应该会有很大的好处。也许,过一段时间,等我手上的项目不太多的时候,我也许可以写一个这样的东西出来。

一个问题,在C++中,如何表现“包”呢?不明白,要想办法查查看。

Subscribe with Bloglines



2005年2月22日星期二

周末郊游

兜风一整天,拍了几张照片。

照片链接:Outing

2005年2月19日星期六

Everything About Everything

前天我工作所用的Windows忽然不能启动,重装系统也告失败,所以就只好向IT部门求助了。
IT部门的兄弟说,尽快给我送个哥们来帮忙。
于是我就一直待在办公室里等待。可是,这两天,恰好,IT兄弟们赶上了农忙季节。竟然把我凉拌了一天也没有人来理我。
于是,我只好在办公室里看文档。把之前想看而没有时间看的文档全读完了。
之后开始读书,一口气读完了五章《ASD》,连读书笔记都写了三篇。

晚上回家的时候,在路上听iPod,听到了《the Big Blue》配乐二。一开始穿插了很多电影中的台词。
Enzo声音低沉,磁力无限地说:“welcome to blue”。

这几天来,每日的天空都干净得耀眼,晚上星空灿烂。
我已经熟悉了北斗星和猎户星座。昨夜,在回家的时候,又凭着中学时代的记忆,顺着北斗七星,在北方天空中找出了北极星。
发现每日上班走的148路,几乎是完完全全的正南正北指向。

iPod中,传出了Enzo和Jacque的对话。
What do you want to know?
Everything.
Everything about what?
Everything about everything.

〖转贴〗中国人的种族观念

【若昔难得 按:】写这文章的人是个爱尔兰老外。于国人而言,对于他的指针,可能有很多都会断然否决,或曰以偏概全。
也许是以偏概全,也有可能是旁观者清。
中国正在迅速地走向世界。之前,中国较少接触外面的世界,所以种族观念并未彰显。
而现在,与外界的联系日益加强,中国之国力也与日渐进,种族问题确实是值得国人注意。

就该文所讲的具体实例,在我自己的身上,也有那么一点痕迹。
比如,一般情况下,我管外国人为老外,但是,对于黑人兄弟,我却常常会称之为黑人。
我可以用这个理由来辩解,在我们常见到的老外中,黑人兄弟比较少,所以称黑人,有更准确的指向性。而且,我确定,自己对于黑人没有任何偏见。
但是,如今仔细想来,黑人兄弟发现自己在中国,竟然连“老外”的称呼也不能享用,应该是有点不爽的。
所以,我今后,一定会注意对于非白人老外的称呼问题。
称呼事小,然种族观念问题事大。而且这种观念,就是在这么一点一滴中慢慢积累起来的。

原文链接:中国人的种族观念

〖转贴〗1905:三种力量角力中国

【若昔难得 按:】一百年以前,“山雨欲来”。保皇派、立宪派、革命派,只是这百年风云的开始。之后的风起云涌,到有点不知如何说起的意味。
转念间就想到一句话,百年如一梦。
不过立刻就明白,所谓“梦”的说法,是不折不扣的bullshit。
凡走过必留下痕迹。
百年之后,再回头来看,2005又留下了什么痕迹。

原文链接:1905:三种力量角力中国

〖转贴〗让我们接近星星

【若昔难得 按:】先哲康德有句名言,头顶的星空与心底的良知。这话听起来很cool,有种让人感动的意思。
然而,我以外,越是让人感动的口号,我们越要加以提防。仔细分析,他究竟是在说什么,有何依据。理性是人类的最强武器,一定要善加利用。以上所说的,并非针对康德的这句名言。
在下对哲学家们先是敬而远之,后来又是敬谢不敏,所以对哲学家们实在是有点距离感。
单就康德而言,我倒是零星地读过他的一些言论。他的理性和反宗教的一面,很为我欣赏。大概算是哲学家中,最对我胃口的那一支了。
什么是头顶的星空呢?康德似乎是指无法穷究的自然运行规律。
是的,在人类有限的时间中,我们是无法穷尽这世界背后的规律的。然而,我们可以知道的,可以作到的,却远比大多数人心目中的那个界限更大。
实际上,这个世界上没有神,(相信神的诸位请原谅在下身为骄傲的无神论者的狂妄)更没有神定下的界限。
科学是没有边界的。

原文链接:让我们接近星星

《ASD》设计模式:NULL Object

CFoo * pcf = bar.GetFoo();
if ( !pcf && cf.Ready() )
{
pcf->Execute();
}
这是一段非常常见的代码。但是有人觉得!cf的写法不够优雅,就说可以用NULL Object模式来简化这种写法。

NULL Object模式大致说来,就是从当前的CFoo类中,派生一个CNullFoo类出来,这个类什么事情也不做。比如说他的Execute函数可能就是一个空函数。
然后,当bar.GetFoo()失败了,原本要返回一个NULL的时候,就返回这个CNullFoo类的实例。
于是,在调用端,就不用做!pcf的判断了,不管GetFoo结果如何,都可以一致的对待。

这个方法虽然看起来不错,但是好像没有省多少事,却还增加了一个类,是否有点不值呢?

对于像我这样的C++程序员来说,可能不会马上想起nested class,但是《ASD》一书,是使用Java来写例子程序的。
所以,这个CNullFoo类,其实是CFoo的一个Nested Class。这样,这个方案就可以接受了。
但是在C++中,我还是觉得这个模式是没有什么价值的。

顺道一提,我对Java的看法。
我热爱C++,所以对于Java多少会有点欠缺热情。不过我希望我下面说的话尽量公正。
一般说来,C++有两大缺点,一个是和C语言兼容,一个是复杂性。
就和C语言兼容而言,确实不爽。然而,这更多是编程习惯的问题。大家都知道,那一部分是C++中不太光彩的部分,那么不要去用它不就好了吗。(我要故作天真状了。)
而对于复杂性,我个人觉得,还可以接受。相反倒是Java不够复杂,就丧失了很多非常cool的特性,而变得不够灵活。在复杂和受限之间,我宁愿选择复杂。
但是Java有两个特性,使我非常艳羡的。
一个是语言的动态性(反射机制),另一个是nested class。都是目前的C++在语言一级上,很难实现,又非常有用的东西。不过,好像在C++/CLI中,这两个特性都会出现。
^_^ 这太让人期待了。

《ASD》设计模式:Singleton和Monostate

Singleton几乎是最简单的模式了,我甚至认为,在一般情况下,他不是模式,而只是一个idiom。
但是,他确实功能强大,而且非常实用,又很常用。(所谓居家旅行杀人灭口必备之工具)
关于Singleton没有多少可以说的了。一句话的解释是,利用静态指针或引用来维护一个系统中某个类的唯一实例;利用静态方法来获取这个唯一实例;是全局变量的优雅替代。
《ASD》一书中,也没有对Singleton讲出多少新意来。

对于利用静态变量做出来的技巧,都可以考虑用模版类来自动化。Singleton就是一个非常好的例子。这个问题我会在以后关于《Modern C++ Design》的记录中来讨论。

Monostate模式却有些新意思,甚至有点搞笑的味道。
如果,以各类可以有多个实例,但是没个实例中的成员都一样,那又如何?那就是说,不论这个类有多少个实例,其实每个实例使用的内存都是同一段静态内存。每个实例都是同一个实例的不同化身。这也算是全局变量的优雅替代。
但是Monostate的实现要比Singleton来的麻烦,必须把每个变量都声明成静态变量。
那么这样做有什么好处呢?
《ASD》如是说:
透明性:使用者使用Monostate对象和使用普通对象没有什么区别。
可派生型:每个Monostate对象的派生类依然是Monostate。(我的理解是,这个特性的前提条件是,派生类不能添加非静态成员变量)
多态性:派生类中可以override父类的方法。
我认为透明性其实没有什么意思,而且有点危险。如果调用者不知道自己调用的是Monostate,而把它当作普通类来使用,那么Monostate的表现可够她大吃一惊的。
可是后两个特性却很有意思,非常有意思。
仔细考量Monostate的内存布局。所有的monostate派生类都共享同一块内存,但是派生类的函数内容却有所不同。也就是说,如果把所有的monostate类对象看作是同一个对象(从内存的角度来看,他们也的确就是一个对象),那么这个对象的函数会根据调用点的不同,而由不同的表现。
即,这个对象的功能可以响应当前的状态。这是一个非常优雅的状态机
这就是Monostate模式的真面目,全局唯一的状态机。
如何实现Monostate模式的状态机,关键一点就是,在父类中,包含一个到子类的指针。父类的所有函数,都委托给该指针指向的子类对象。子类的函数,在状态切换时,把这个指针改变为指向下一个状态子类的实例。

《ASD》设计模式:Facade和Mediator

Facade模式和Mediator模式有些相似,虽然尚未相似到令人混淆的地步。在形式上他们是有明显区别的,在功效上却有共通之处,这样的相似更应该注意。
按照GOF的《Design Patterns》一书,Facade模式和Mediator模式都是用于连接多个类,简化类之间的联系。
Facade模式是把大系统藏在自己后面,由自己来做一个通用的接口。使用者不用关系下面的具体类,只要了解Facade的接口,就可以使用系统了。这几乎是最常用的设计模式了。
Mediator也是连接大系统,但是它的客户并不是系统的使用者,而是系统中的各个模块;相应的,它的目的只是为了降低系统中各个模块之间的依赖关系。而对于系统的使用者,Mediator常常是透明的。

《ASD》一书中,不仅强调了这两个模式的更多特性,还挖掘了这两个模式之间更内在的关系。即他们都是为了施加策略,Facade模式是从上面施加,Mediator是从下面施加。
所谓策略,即如何使用系统中的模块。
于此一说,如何应用Facade模式来施加策略就昭然若揭了。既然调用者只是发出命令,由Facade对象解释命并调用系统中的模块来执行命令,那么Facade对象就可以在执行时,控制各个模块之间的关系了。
这个有些Template模式或Strategy模式的味道。
由于是从调用这一端执行,所以可以说,这是从上面施加策略,或者可以说是一种主动策略

在《Design Pattern》书中,Mediator对于系统的客户是透明的,但是系统中的各个模块基本上都还是指能够看到Mediator。
可是在《ASD》书中,Mediator对于系统中的各个模块基本上也是半透明的了。
Mediator知道所有的模块,和他们之间的关系。
而各个模块并不知道Mediator的存在,它们能看到的,只是一个消息系统,有事就发消息。
当然了,Mediator就在消息系统的另一端倾听。一旦收到了某个模块的消息,他就开始调用相关的其他对象,牵动整个系统。
策略就是如此在系统内部运转,这是这次除了Mediator自己以外,没有对象知道,策略已经开始运作了。
所以可以说,这是从下面施加策略,或者可以说是一种被动策略

两者相比较,主动策略来的更直接,力量更强大。但是如果调用着绕过Facade的接口,直接与系统中子模块对话,策略就会无法实施。
被动策略是隐蔽的,是以相应的方式来运作的,在策略的实施上,有些限制。但是没有模块知道策略的实施,也就不能绕过这些策略。

2005年2月17日星期四

《ASD》设计模式:Template和Strategy

Q:virtual函数可以是private函数吗?
A:可以。不仅可以,这还是Template模式中的常见方法。
Q:那么子类实现这些不能被调用的虚函数有什么意义呢?
A:意义在于这些虚函数是由一个public的非虚函数来调用的。
Template模式的核心是有一个相对固定的调用框架和可以被替换的具体步骤,父类实现这个调用框架,子类实现具体步骤。如果不想让客户随便的使用这些具体步骤,就可以把它们设为private函数,只能由父类的框架来调用。所以,对于一个类似于framework的产品,Template模式几乎是必不可少的。

Template模式是一种非常强大而且有趣的模式,但是它常常会被滥用。根本原因是:仔细考量Template模式的结构,会发现Template模式的实现完全是依靠继承。而GOF说过,要优先考虑聚合然后才是继承。
Template是直接继承,这使得具体实现的子类依赖于调用者父类,这不符合DIP原则(还能想起什么是DIP吗?)这就使得子类中的方法不能为其他对象所用。而常常,对于一个具体实现有不止一种策略,而每种策略都需要这个具体实现中的某个方法。这种时候,Template模式会变得很麻烦。
那么如何才能让它符合DIP原则呢?这就需要在调用者和实现者之间添加一个接口。这个接口声明所有的可能被调用的步骤;调用者包含这个接口,调用接口中的方法;实现者从这个接口中派生,实现接口中的所有步骤。
这个改动将大大地改善之前设计的灵活性。多种策略可以共享同一个实现了,当然一个策略也可以应用于多种实现上。策略和实现之前完全的松绑了。
实际上,这种设计是把之前的Templage模式便成了Strategy模式。
所以当,涉及到要把上层逻辑和下层实现分离的时候,应当优先考虑Strategy模式,而不是Template模式。

那么Template模式是否就没有用了呢?看到这种问句的人都该明白,答案一定是否定的。
刚才已经提到了,Template模式的问题之一是实现者的方法不能被其他对象使用。
而本文一开始就说了,Template模式可以把虚函数设成私有函数,以防止其他对象滥用具体实现类。也就是说,这是一个故意加上去的限制。
现在明白了吧,Template的不灵活原本就是他的意图,本意就是要给使用者添加一些限制。例如一个framework的产品,并不希望出现自己所不愿意见到的调用方法(那样也许会对产品本身造成破坏),所以就会使用Template模式。

结论是:Template模式在于限制,Strategy模式在于分离。

2005年2月16日星期三

《ASD》设计模式:Command和Active Object

Command模式:
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. - 《Design Patterns》

Command模式的关键在于只包含一个 Execute方法,子类在实现这个接口时,在Execute方法中,完成特定的任务。可以说,这是一个非常简单的模式。
《ASD》中提到了该模式的三种用法:
1. Invoker可以和任意一个Command挂钩,而且不需要了解这到底是个什么ConcreteCommand,然后在需要的时候调用这个Command对象的Execute方法就行了。这在消息驱动的的系统中非常常见,每个trigger就是一个invoker。那么如何把Command和invoker挂钩呢?方法很多,最cool的方法是在系统外用一个配置文件来指定。这样不需要重新编译就可以改变软件运行的方式。可以参考Source Insight的界面。Source Insight中可以任意配置菜单项和工具栏按钮。其实现应该就是应用了这种Command模式。
2.上面的方法是否让人想起了Template模式?有点相像吧。顺着这个思路去想,就可以把Command模式应用于Transaction。让一个类来解决Transaction的init和uninit问题,中间包含一个Command的队列。这样就可以把这个队列中的全部command当作一个transaction了。这样的作法可以把Transaction的实现和逻辑分离开来,是很漂亮的实现。同样的思路,也可以用在类似的问题上,需要init和uninit,中间有不定量的操作。
3.如果真的用来解决transaction问题,那么就必须具备roll back的能力。然而这个很容易实现,只要在command类中,添加undo方法就可以了。剩下的活交给invoker来处理。
4.此外还有一个附带的好处。command类和一个单独的execute方法其实很相似,但是command类的对象有生命周期,可以由程序来控制。因此,一个command对象,可以在提交了很长时间以后再批量执行。
除了这些以外,《Design Pattern》还提到了Command模式的其他使用方法。虽然这些方法未必使用,但我还是把它们列在这里:
1.command对象和command对象的序列都可以serialization。这样如果软件被有意或无意的中止(例如crash),在重新启动后,还可以接续之前没有完成的任务。
2.Command模式如果和Composite模式接合,就可以作出MacroCommand。^_^,这个idea虽然很cool,但是可以用到的地方大概不多吧。

Active Object模式不属于《Design Pattern》23模式。实际上,她是一种特殊的Command Queue。其特殊之处在于:
1. 队列的拥有者会顺序地执行队列中所有Command对象的Execute方法。(这个其实不算特殊)
2.Command对象在自己的Execute方法结束前,可以把一个新的command对象(实际上常常是这个command对象自己)再加到队列的尾部。
看出来了吗,这个队列有可能不会终止的,他可以一直执行下去。这个可以作为一个应用或者服务的主模块了,想像一下她可以作多少事情吧。
《ASD》指出这个模式可以用来在一个线程中处理多任务的问题!!! ^_^ 太cool了。
如何处理呢?你可以把每个command对象看作是一个任务。他在Execute函数中,处理自己的任务,在任务告一段落时,记录自己的状态,然后把自己插入到队列的尾部,结束Execute方法。当队列轮完一周后,又会再次执行这个command对象的Execute方法。 ^_^ 很cool吧。
那么这种方法和多线程的方法相比有什么有缺点呢?
最大的优点是,所有的command都在同一个线程中,因此切换时,不需要进入内核模式!!超高效啊!!而且,可以有很多很多的command,数量上远远超过多线程的数量。
缺点嘛,是这种方法需要用户自己来实现调度,另外这其实是一种非剥夺模式的多任务,如果command处理不好,就会连累其它所有的command,因此实际上比多线程要更复杂。(嘿嘿,程序员能够怕麻烦吗?)
还有一点,Active Object运行于单线程,也就是说,她不能享受多处理器或多处理器核心带来的性能上的改善。
其实,这最后一点是非常致命的一点。也就是说,在当前intel的超线程CPU机器上,如果系统的负担并不重的时候。Active Object的效率有可能比多线程更低。
Anyway,这是一个非常有趣的模式。只是一般的程序员可能没有机会用到。但是请记住她,也许能有那么一次机会,可一用她来爽上一把。

异形中的两只狗

去年年底的时候,复习了一遍异形四部曲,看到一个很有趣的细节。在第一集中,Ripley养有一只小狗。很乖巧的小猎犬,就是Snoopy那种。
电影的后半段异形在飞船中,横冲直撞,大肆屠杀。可这只狗却安然无恙,虽然她也曾经被异形追踪过。在异形四部曲中,能够从异形口中逃生的,除了女主角Ripley以外,就是这只狗了。最后,飞船上的船员,除了Ripley之外,全都被杀死。只有Ripley和小狗乘坐救生船逃生了。
是小狗的求生能力很强吗?当然不是,只是导演很强而已。在好莱坞的电影中,坏人可以死,好人可以死,连世界毁灭也不算什么,可是杀死一只无辜的小狗,那可就真是大事件了。
所以,第二集中,Ripley一醒来,首先就要去找那只小狗,小狗没事就好。至于Ripley在太空中漂流了70多年,连女儿都已经死了。观众于此,虽然有些感同身受的伤感,却也还能够接受。
之后,Ripley第二次出发去和Aliens干架。这次如果再让异形们把人类杀个干净,偏偏留下小狗作活口,剧情上就太不通顺。可是又万万不能杀小狗,怎么办呢?导演这次把小狗留在家中了。让女英雄Ripley一个人去拼命吧。
到了异形第三集的时候,导演换成了新锐大卫芬奇(David Fincher)。这哥们尽管现在很牛,可在异形第三集的时候,即没有拍Se7en,也没有拍Fight Club,仍然是个毛头小伙子。所以他一心要把异形第三集拍成一个反传统的电影。其决心之大,在于电影故事还没有开始,就把第二集中和Ripley有点感情戏的大兵和Ripley拼死救出的小女孩给杀了。我敢肯定,如果第二集中,Ripley把那只小狗带在身边,那么那只小狗也必定会被大卫给杀掉。
可是没有杀狗,多少让大卫有点不过瘾。所以大卫安排异形首先寄生在监狱里的一只狗身上,然后破狗而出,再大肆咬人。对观众来说,杀狗可比杀人要震撼多了。所以,荧幕上,异形可以把人撕碎,但是绝不能正面出现异形杀狗的场面。
后来,异形第三集的DVD中,有一个加长版,并不是由大卫剪辑的。在这个版本中,异形寄生的是一只牛,而不是狗。没有杀狗的情节了。
我看DVD的时候,首先看的是加长版。看到牛被杀死的时候,确定这个加长版是个垃圾,然后就切换回原版去看了。

提到电影中被杀死的动物,让我想起,在教父第一集中,有个很出名的情节。
教父为了威胁电影制片人,把制片人的马杀死了,再把马头藏在制片人的被子下。制片人醒来时,被吓得半死,然后就乖乖听话了。
科波拉在教父DVD的评论音轨中提到,电影上映后,有很多人打电话或写信来批判为了拍电影就杀死一匹美丽而无辜的马。
科波拉解释他们并没有杀马。他们本来打算用一个假马头来拍这段戏,可是效果不好。后来他们发现有宠物食品公司用马肉来作宠物食品罐头,于是他们就找到宠物食品公司,选了匹漂亮的马,买下了马头,用来拍了那段戏。当然,马的身体还是被用来作成了罐头喂给了猫和狗。

未成年天后

从网上下载了法国未成年天后Alizee的两只MTV,看了以后,的确有点惊艳的感觉。Alizee出生于1984年,15岁就创下了百万销售成绩。虽然非常年轻,脸上稚气未脱,但台风却稳健成熟,很有些巨星的味道。

不由得让人想起另一个年幼成名的法国巨星Sophie Marceau。Sophie为广大国人所知大概是从braveheart开始,但其实她是由她的电影处女作《初吻》而成名的。而那时她才刚刚14岁。

看看《初吻》时的Sophie和现在的Alizee,到有些相似的地方。都是掩盖不住的青春年少咄咄逼人,却又充满了成熟性感的味道。
不由得想起张爱玲年幼时说的那句话,“成名要乘早啊”。
以前我是小生,如今都可以自称老夫了,却也没有能够成名。确如张爱玲所说,“快乐也不那么痛快了”。
张爱玲在这篇喊出了“成名要趁早”的《天才梦》中,还有更棒的一句话,“生命是一袭华美的袍,爬满了蚤子。

相关链接:
Alizee的两支MV,都是720X480的高分辨率。下载时注意量力而行。
La Isla Bonita
I'M Fed Up

2005年2月15日星期二

《ASD》:Principles

Agile Software Development是一本很棒的书,主要是因为作者是Robert C.Martin。当年我在ObjectMentor的网站上,读Robert C.Martin的文章时,就经常有背后的寒毛都竖起来的感觉。他对模式的理解和应用,常常让已经把GOF那本书读了四五次的我感到自己对模式还没有入门。
这本Agile Software Development我只看了一半,而且有一个多月没有看了。
所以我打算复习一下,然后把她看完。
今天复习的内容是Principles。
在我看来,Principles是软件设计的基础。和patterns不同,Principles不能直接解决任何问题。但是她是衡量设计好坏的标准,定下了设计的目标。
在复习之前,先回忆一下,能够想起的Principles有这么几个:
SRP,Simple Responsiple Principle,单一责任。即是,每个类应该只承担一个责任。衡量的方法是,在系统中,一个类只会随一种变化而改变。然而具体实现中,这是非常难以作到的,更实际的目标是针对接口。每个接口只承担一个责任,而继承了多个接口的类,就承担了多个责任。
OCP,Open Close Principle。即是对功能的扩展Open,对代码的修改Close。在不修改当前代码的前提下,只是添加新的代码,就可以扩充功能。实际上,没有绝对的Open,也没有绝对的Close。无论如何抽象接口,分离实现。代码中,总有一点是需要修改而无法close的。但是随着动态语言特性的引入,我想,设计中对OCP的支持将会被大大的增强。
替换原则,想不起来英语简写了。(三个字母的黑话太多了 ^_^)字面的意思是父类的应该能被子类替换。实际上,是指子类不应该扩展父类没有的接口。更深层的原因是,如果子类公开了父类没有的接口,那么在使用时,调用者将会判断正在使用什么子类,是否可以使用扩展接口。这就使得调用者依赖于具体的实现,造成了高耦合。那么如果子类一定要扩充接口怎么办呢?答案是继承多接口。
依赖倒置原则,想不起来英语简写了。(三个字母的黑话太多了 ^_^)相对而言,这个原则比较容易理解。即是,模块之间不应该有直接的依赖关系,而应该通过抽象的接口联结起来,彼此不关心对方的具体实现。这个principle虽然容易理解,然而在实施上却是颇为困难。
剩下的principles就想不起来了。现在去看书,一会儿来更新。

复习以后的更新内容:
1. SRP,没有什么可以说的了。
2. OCP,没有什么可以说的了。
3. 替换原则的简写是LSP。子类不仅不应该扩充接口,而且也不能消减接口。总之不能让客户者针对实现作出判断。然而,我现在想来,这与GP中的traits的用法似乎有点不合。关于这个问题,我要仔细想想。结论大概是,traits的用法是,实现者根据调用者的不同,提供不同的实现,但是仍然保持着接口的不变;对于调用者而言,不同的实现还是透明的。
4. 依赖倒置原则是DIP。更容易的理解是,所有的依赖方向都应该是由实现到抽象,并终结于抽象。具体一点的说,上层模块要定义自己需要调用的接口,并使用这个接口,所以依赖这个抽象。下层模块要实现上层模块定义的接口,所以依赖那个抽象。两层模块的实现都依赖于同一个接口。
5. 没有想起来的原则是接口隔离原则(ISP)。实际上是说,要避免胖接口,尽量使用瘦接口。核心思想是,不能强迫客户包含他们并不需要的接口。也就是说,不要单一的大接口,要有很多的小接口。实现可以使用多继承,也可以用包含的方式来实现这多个接口。

其实,以前就觉得,Robert C.Martin和其他大师相比,非常倾向于使用小接口和多继承。如今看来,他有一大堆的Priniciples来支持自己的这种设计。

2005年2月13日星期日

Heartbreak Heartbeat

今天和两个同事去看电影。这几天,在Oscar快要到来的时候,虽然有不少很棒的电影上映;但是,考虑按照我们的英语听力,如果选择The Aviator, Million Dollar Baby或者Sideways,都会有些浪费的感觉。(虽然我很期待Sideways)
所以我们最后选择的是13警局。这电影与我们所设想的东西完全吻合,是完全没有什么可以说的了。

然而在电影之前,却偶然看到了一个很棒的广告。黑白的广告,穿插着巨大的New York中的琐碎生活,修鞋匠的手和锤,憔悴的华人的脸,白色的袜子和拥抱而舞的老人,房屋街道大楼,消防员警察和玩篮球的人。
广告的第一句台词,“My oldest friend My first love”让我很有感觉,那感觉一直持续到最后一句广告词,“My card is american express”,就被彻底的破坏了。
画面中有张晃动的苍老的脸,依稀是Robert Di Niro。这让我想起了那部伟大的电影《Once Upan a Time in America》。面条在“yesterday”的音乐中,回到他的故乡大苹果NY。那里曾经有他最好的朋友,有他的初恋,有他的青春梦。而现在,一切都变成了Yesterday。
城市是人群聚居的地方,对于每个人来说,城市却是一个私人的体验。她和人一起长大的,一起成熟,一起老去。那不仅是一个地理位置,更像是一个记忆的标签。
心脏怦然而动,周围的一切都淡去了,那一刻犹如永恒般的漫长;抑或,心脏如撕裂一般的痛苦,无法行动,只能停下来咬牙忍受。当思绪触到那标签的时候,这些记忆依然鲜活得犹如就在脑后。

回来以后,google了一下,才知道,那演员果然是Robert Di Niro,而导演是Maritn Scorsese。全部的台词如下:
My oldest friend My first love
My east My far east
My west side My private side
My heartbreak My heartbeat
My life happens here
My card is american express

无论画面和语言如何的精致,这还是一个商业广告。在翻动伤感的回忆之后,是赤裸裸的“My card is american express”,确实让人非常的不快。

从下面这个链接可以观看或下载这个短片:american express

2005年2月9日星期三

中国怪物 新春

时差16个小时以外的地方,现在已经是他们的新年了;本地的时间在中国人的说法中是大年三十,虽然本地人大多不知道这个称谓。
这让我有些困惑,犹如春节本身也让我有些不知该如何面对。
我不喜欢春节。传统的春节里,每个人都有固定的行为模式,拜会成堆的由各种亲疏远近关系连起来的数不清的人,说一些不解其意的吉祥话,傻乐之后回家睡觉。
人们在这些日子中都要以团体的形式出现,杂烩成一锅,个人自由欠奉。
关系人情人伦礼仪,中国人传统中维系整个社会关系恒久不变的那套法门,就在这数日中轮番上演。
所以我真挚地不喜欢这个节日。
我宁愿在这个假日中,把自己关在家中,看书看碟大笑打屁,间或吃饭睡觉,不分白天黑夜。
这是我最愿意的,在寒冷而漫长的七天假期中,所作的事情。
然而,七天的无日无夜以后,才会明白,原来我也未能正视那个被称作“年”的中国怪物。
那个我爱的,我恨的,我想离开的,却永远也无法放手的怪物。

16个小时以前,时差16个小时以外的地方,还是中国人称为大年三十的时候,我和几个同事,坐在Redmond的老四川饭店,点了一盘水饺。我们商量,那一天才是我们的年。最后决定和中国同步,按着北京的时间来吧。
当今天早上,我离开公寓去公司的时候,在中国,刚好是新一年的第一个小时。在中国,人们寒暄,孩子嬉戏。他们还有半个黑夜,才能见到新春的阳光。
而在Redmond,在我的路上,我看到天空是均匀的蔚蓝色,灌木枝条的末端有粉红的芽,走在草地上,脚下传来冰凌被踏碎所发出的“咔嚓咔嚓”的声响。

2005年2月7日星期一

〖转〗光的真理

〖若昔难得按:〗
在光的问题上,真理只有一个。
在很多时候,当人们说没有对错是非之分的时候,真理还是只有一个。
否认这一点的人,常常只是不愿或不敢或不能看到那个真相。

插一段题外话,这篇文章中提到了牛顿。对于大多国人来说,牛顿的名字是和苹果连在一起。我宁愿相信那个苹果的故事是牛顿的一个joke。
如果那个故事是真实的,那么在中国也有一个类似的故事。朱熹看到井里的白气,就悟到这个世界是由阴阳二气组成的。
为什么,两个相似的故事之后,一个人带来了伟大的经典物理,另一个人则满嘴胡话呢?
好象又回到了那个经典问题,答案依然是,推理和实证是科学的基础,缺少了这样的基础,就只能臆测和胡说了。

原文链接:光的真理

2005年2月4日星期五

〖转〗杨振宁:在科学与玄学之间

方舟子所写的这篇《杨振宁:在科学与玄学之间》虽然由杨振宁生平讲起,但其实话题还是落在了所谓的李约瑟难题上。
爱因斯坦给出的那个答案,“古代中国学者不懂得形式逻辑体系和实验验证,因此没能发展出近代科学”,在我看来,比杨振宁的答案更为确切。
我以为,实际上,形式逻辑体系和试验验证的缺失是《易经》产生的原因,而非《易经》的结果。
只是,在中华文明中,为何没有能够产生形式逻辑体系和试验验证,确实是一个问题。
爱因斯坦的言下之意,这是一个偶然的结果。
那么这个偶然也过于悲哀了。

原文链接:〖转〗杨振宁:在科学与玄学之间

故事和道理

黄章晋在《理直气壮地无耻——我读《狼图腾》》一文中,开篇就写到:

很多中国文人最爱的智力创造是这样一种东西,先编个故事,然后根据故事讲述一番很大的道理。如果你不明白,随便找本《读者》,我马上可以找出十篇来。通常,这十篇里有八篇讲的故事一望而知就是不可靠的,或是作者生编,或是作者智力不逮当了回谣言二传手。接下来的奇观是,这十篇里还有八篇,道理根本就说不到点子上。

黄章晋在这里用《读者》来作例子,后面开始谈论《狼图腾》。对于没看过《读者》或《狼图腾》的人来说,还可以参考各种所谓的心灵鸡汤。这样的故事和道理在网上漫天飞舞,一抓一大把,一不小心还会飞进自己的邮箱。对于这样的文字,我一般的作法是直接删除。觉得不爽的时候,就用黄章晋的这段话reply。
对于年幼者或智力低下者,有时讲故事比讲道理要更容易理解一些。但是我相信对于一个智力正常的成年人,使用比喻之类的手法来传达思想,实在是一种有辱智商的行为。


2005年2月3日星期四

微软发布MSN Search

本周微软发布了自己的搜索引擎MSN Search,这是微软潜心于搜索引擎多年以后的成果,其中也有不少是北京的微软亚洲研究院的功劳。这是微软用于挑战Google的武器。
这两天中,在公司内的各个角落,办公室、电梯、食堂、车辆,全都是MSN Search的广告。
试用了一下,MSN Search也的确有自己的过人之处。除了新闻,音乐,图像,桌面搜索这些google也有的东西以外,MSN Search还支持对于微软自己的百科全书软件Encarta的搜索。
另外,有一个叫Near Me的搜索模式,可以返回和用户的地理位置比较接近的页面。
还有一个叫做Search Builder的工具,可以帮助用户创建复杂的搜索条件,而无需去记忆那些复杂的搜索命令。
可惜的是,MSN Search还不支持中文界面,但是用中文搜索是没有问题的。

和MSN Search相关的几个页面:
这个是MSN Search的首页:http://search.msn.com/
这个是MSN Search的blog:http://blogs.msdn.com/msnsearch
这个是MSN Sandbox,有些新鲜玩意,当然也包括MSN Search:http://sandbox.msn.com/
这里有MSN Search新特性的介绍:http://www.imagine-msn.com/search/tour/moreprecise.aspx

2005年2月2日星期三

Good Luck Killer

早上跑完步以后回家,在condo附近见到一只灰色的猫。
猫走得不紧不慢,很悠闲的样子。尾巴直直的竖起来,那是猫心情很好的表现。
我蹲下来,把手伸向她,撮着嘴挤了点声音出来吸引她的注意力。
那猫立刻小跑到我的身边来,闻了闻我的手,然后用头颈蹭了蹭的手。我怀疑她饿了。抚摸她的身体的时候,发现她很胖,看来是从来没有挨过饿。她的脖子上戴着一个项圈,上面还有一个小铭牌。
她围着我转了两圈,就向我的身后走了。
我站起来,四下看了看,周围没有人。我心里觉得有些不妥,看来那是一只流浪猫,而且刚刚开始流浪。
于是我追了上去,叫住那只猫,然后把她抱了起来。真的很沉啊,身体软软的,好象没有骨头。
猫开始挣扎了一下,然后就老老实实地仰面躺在我怀里了。
我看了看她的铭牌,上面写着“Killer”,还有一串本地的电话号码。
^_^,这么肥胖又温顺的猫,居然叫这个名字。
然后这时,我身后开来了一辆汽车。Killer被吓了一跳,从我怀里一下窜了出去,跑开了。
我赶紧在心里重复了两次那个在铭牌上的电话号码。然后回condo去,拨了那个号码。
是个男人接的电话。我告诉他,我在附近看到了他的猫Killer,然后告诉他地址。那人说马上过来。
我挂了电话之后去洗澡。刚洗完澡出来,就听到楼下有人喊“Anyone found my cat?”。我赶紧穿上衣服下楼,告诉他是我打的电话,然后领他到Killer最后离开我的地方。
我问他,“Is it she or he?”他说,“It is he.”^_^
他说他会找到Killer的。我说“good luck”,然后转身离开。
回头的时候看到,他还在那一带搜索,嘴里念着“KillerKillerKillerKillerKillerKiller”
我想到Killer的发音和Kitty有点象,这应该是英语里很常见的猫名吧。
等我上楼收拾好东西,出发去公司的时候,那个人已经不见了。大概已经找到他的Killer了吧。

走失的宠物猫对于猫主人、猫自己和周围的环境来说,都是很痛苦的。所以希望每一个养有猫的人,照顾好自己的猫,给她配上铭牌,留下自己的联系电话。也希望发现流浪猫的人,能尽可能的帮助她回到她该去的地方。

很遗憾,我没有留下Killer的照片。

2005年1月30日星期日

转贴两篇方舟子的文章

经常觉得自己很懒散,表现之一就是,每天上午基本上作不了什么事,下午就能作一些事了,晚上效率就更高了,但还是比不上从公司回公寓的路上时的态度,一回想今天浪费了多少时间,就觉得痛心疾首,下决心明天一定要洗心革面从头来过,决不浪费时间了。
其实人都是这样,倾向于把事情留到deadline之前的最后一分钟来完成。
所以这让我想起了方舟子写过的一篇文章:〖转〗人不是基因的奴隶。其中提到相似的现象在猴子身上也能看到。看来是这灵长类生物的共性,让我觉得心里好受了一点。
在方舟子最近的另一篇文章〖转〗神龟虽寿,犹有竟时中,方舟子谈到了关于物种保护的问题。在进化的过程中,大部分的物种都已经灭绝了。其实这是一个很正常的过程,也没有什么可惜的。但是对于人类对它们的濒临灭绝负有责任的物种,那么还是应该竭尽所能让它们的生命尽量延续。那么,我们是否有必要一定要延续熊猫这个物种呢?我们每年为了保存这个早就不该在大自然中存活的物种,已经投入了太多。我想从生物或经济的角度来考量,应该是没有什么必要了。但是这个物种上所携带的文化或政治含义,已经远远大于了她在其它方面的价值,所以我们会尽力让她继续生存下去的。

相关链接:
〖转〗人不是基因的奴隶
〖转〗神龟虽寿,犹有竟时

碧海情

第一次看《The Big Blue》这电影,是在80年代的电影院里,那是我最初开始热爱电影的日子。之后的一段时间中,又在电视上看了若干次。直到现在,我也依然认为这是大陆引进电影中最棒的一部。
关于遥远的那次《The Big Blue》的观影经历,只记得几个片断了。
Jacque和Enzo在水下比赛谁坚持的时间更长,结果两人都是被人横着抬走的,Jacque躺在旅馆里的床上,给Johana看自己钱包里的照片,里面只有一张微笑的海豚。Jacque说,这就是我的家人,我唯一的家人。
这几乎是我所看过的电影中,让我感到最寂寞的一段了。
昨天,又看了一次《The Big Blue》。
Enzo曾经要Johana小心Jacque,因为Jacque是来自另一个世界的。但Enzo肯定是属于这个世界,他热爱狂欢,热爱胜利,热爱大海。他的死亡只是由于他的爱。因为同样对大海的热爱,Jacque和Enzo成了最好的朋友。
但是Jacque和Enzo是如此的不同。喧嚣而虚假,Jacque眼中的世界大概如此,这让他感到恐惧。Jacque总是沉默不语,因为言语是如此的没有意义。人总是会离开或者死亡,没有征兆,犹如他的母亲和父亲。所以他热爱大海,热爱海底,在那里,冰冷而黑暗,而他也才能真正的宁静。只是过于寂寞了。
因为大到无法忍受的寂寞,Jacque才会让自己爱上Johana,或者以为爱上了Johana。只是这样的爱只能伤害Johana,因为Jacque毕竟不属于这个世界。
最后,Jacque在四百呎的海底离开,虽然对于Johana来说过于残酷,但是对Jacque而言,他只是回到了自己的世界了,带着最真诚最纯洁的爱。

Jacque毕竟不是普通人。对于常人而言,能作到Enzo那样就很好了。

另外,我非常喜欢这电影的色彩,不同的蓝色,浩瀚的、冰冷的、激动的、宁静的。还有贴着海面飞行的镜头,向着水底下潜的镜头,都很漂亮。
还有,电影海报很漂亮。

2005年1月29日星期六

离别E888

昨晚我的宝贝耳塞Sony E888没有任何预兆的突然死亡了。事前我正在观看从网上下载的National Treasure,中途暂停倒水喝,回来后就发现E888的左耳塞失声了。经反复尝试,确认非播放器问题,非接触问题。
这副E888购于2000年,用到现在,也可以说一句“寿终正寝”了吧。在2000年的时候,国内能见到的中高档耳机还很少,耳塞就更少了。E888大概算是那时的王者了吧。实际上,就算到现在,除了舒尔、音特美出品的变态耳塞,E888大概还是我眼中的耳塞最佳选择。
关于E888的音质,简单的说,虽然低音的量少的可怜,但是中音和高音的华丽足以让人无视她在低音上的不足。尤其是人耳最敏感的中音部分,E888的表现真能说的上是丝般顺滑,与我家中的SENNHEISER HD600相比,也不遑多让。当然了,其它部分比起HD600就差远了。嗯,说起HD600,我到是有点想回家了。
没有了E888给我添了一点麻烦,用什么来配iPod呢?好在还带了一副Koss SportaPro在身边,平时是连在计算机上使用,现在也可以连在iPod上用了。只是这东西毕竟不是太方便。也打算了再买一只随身用的耳塞或者耳挂。不过在网上查了一下价格,发现这种东西常常比国内的价格还贵。那还是等回国以后,再去安润搞一个吧。
奇怪了,国内的这种东西怎么会这么便宜?


2005年1月28日星期五

〖转〗教育体制已成中国人不折不扣的国耻

http://www.blogcn.com/user17/likeyesterday/blog/5977317.html
这篇文章中,引用联合国人权委员会教育权报告员托马舍夫斯基在2003年的报告,称中国的教育经费只占全国生产总值的 2%。而按照中国教育部、国家统计局、财政部在2002年公布的数据,这个比例是3.41%。即便按照官方的数据,投入依然太低。

2005年1月26日星期三

怪物

这是今天贴出的第三篇blog。原因是,把前几天的blog都推迟到今天来写了。
推迟的原因是,几天前,在网上看到一部漫画《monster》一看之下,欲罢不能,只有一气看完,所以连写blog的时间都没有了。
《monster》的故事主要发生在95-96两年之间,地点是在德国和捷克斯洛伐克。故事开始于86年的联邦德国,天才的脑外科医生拼死救活了一个10岁的男孩子,之后却因为没有优先照顾病重的市长,而被医院院长冷落。然而不久之后,医院院长就被人毒杀了,同时男孩和他的孪生妹妹一起失踪了。到了95年,医生却突然发现,自己当年救活的孩子是一个恶魔(比喻而已,没有超自然含义),是多起杀人事件的背后黑手,而目的却不得而知。医生独自开始了对恶魔的追杀之旅。这只是这个恐怖故事的开始,其后的黑暗,深不见底。
《monster》一共18卷,一开始看,就感到这故事丝丝入扣、杀机暗伏。人物描写尤其真实,直有在耳后呼吸的感觉。我以为这漫画的七八九三卷描写在慕尼黑的事件,是整个故事中最成功的部分。十余个主要人物被命运之线微妙地联系起来,个个都在苦苦挣扎,探寻事实的真相,网络逐渐成形,要把monster困于其中;然而直到逼近monster,才发现monster的行动早已开始了。
可惜的是,之后的数卷,故事就有些勉强了,结构与节奏都有点混乱,最后有些草草收场的感觉。大概是前面的场子铺得太多,发展到后面,已经长成了一个“怪物”,超出了作者的掌控能力了吧。
让我打分的话,前面9卷是95/100,整体是80/100。如此看来,后面9卷是没有什么看的必要了。实际上,前面9卷确实值得一看,而看了前9卷以后,恐怕就很难停下来了。

见识IMAX的那个下午

上个周末(Jan.23),去Seattle见识了IMAX。
IMAX是一种大荧幕电影系统。当然说起大荧幕,很多人会想起球幕之类的电影。
与这些在马戏团或者科技馆中的玩具不同,IMAX是个真正的商业系统,所以不只是满足观众的猎奇,同时通过荧幕、音响、放映机、胶片格式、甚至具体到座椅等等系统地设计,使观众有最好的影音享受。另外,由于是一个商业标准,因此很多商业电影在制作的时候,就会有专门的IMAX标准。例如最近的电影蜘蛛侠2和Pole Express都有IMAX版。
这次我们去看的是一部纪录片Fighter Pilot。观感嘛,简单地说就是两点,一、眼睛不够用,摇头晃脑才能看完屏幕上的每个细节。二、终于用上耳朵了,光可靠听也能知道声音是从那一“点”来的。
至于更具体的感受嘛,还是应该亲身去体验一下。
在中国大陆,上海有几处影院可以放映IMAX。北京的华星号称可以播放IMAX,但实际上从开业到现在,一场也没有放过。

Life's so light

If I have two lifes, with one life, I could invite her to stay at my place, and the second life, I could kick her out. Then I could compare and see, which had been the best thing to do.
But we only live once.
Life's so light, like an outline, we can't ever fill in or correct, make any better. It's frightening.
以上是电影布拉格之恋(the unbearable of lightness of being)中的一段台词。这个电影的中文名字还真是不知所谓啊,还是说生命不可承受之轻比较好。
抄上这样一段台词的原因是,三四天以前,我看了这部电影,然后想到网上去看看关于这本书或这部电影的评论,却没有什么可以入眼的。甚至有的以生命不可承受之轻为标题的文章,连标题也没有理解,大谈压力之类的话题。所以我想,有必要在网上留下这段话,作为一个标签。
想起小时候看过一段话,说当文人们喜欢以“生命不能承受之轻”“生命不能承受之重”“生命不能承受之痛”“生命不能承受之回忆”“生命不能承受之XXX”来命名他们的文章的时候,那么这是一个米兰昆德拉流行的年代。现在这样的标题都快绝迹了,昆德拉不再是青年们炫耀自己品位的话题。时间确实是流逝得太快了。
生命是如此之轻;时间是如此之重。

2005年1月18日星期二

回忆之前 忘记之后

电影《北京乐与怒》,英语名字是《Beijing Rocks》,张婉婷导演,吴彦祖,耿乐,舒淇主演。单看这串名字,除了张婉婷之外,其他的实在很难刺激起观影欲望,而且在这电影上映的2001年,我对中国摇滚乐已经掺入了不屑的感情,所以这电影我只看了一个开头就放弃了,也因此直到今天,才听到她的片尾曲,《回忆之前忘记之后》。一听之下,茫茫然不知该如何言语,只能胡说一通了。
回忆之前茫茫如梦醒,忘记之后方知梦中还有梦。
唉,回忆茫茫,忘记方知,只是如何才能忘记?
有一种酒,叫“醉生梦死”,喝下之后就可以把过去的事情全部忘记。然而实际上,喝下“醉生梦死”的人,会一直去想我忘记那个人了吗,却才发现那只能让他记得更清楚。
又或者,找一个树洞,把回忆藏于其中。树洞一天不被开启,秘密就一天不会泛起。然而埋了回忆的树,终究会开花结果,每一粒果实全是那回忆的种子,之后枝繁叶茂郁郁葱葱,又如何能视而不见?
回忆不能忘记,就只能放手,放手之后也许才能正视无暇心灵的永恒阳光。

链接:回忆之前 忘记之后 MP3

2005年1月10日星期一

下雪了

今天早上我本来打算出去跑步的,向窗外一看,又下雪了,而且,还有积雪啊。所以赶紧下楼去周围转了一圈,拍了几张照片。
这是我的A80第一次拍雪景,实在是没有什么把握,试了几种模式,回来一看,还是不太满意,只好用图像软件再调整了一下。真希望能再下一次雪,让我再试试拍雪景。
点击这个链接观看雪景照片:SNOW

老狮子与大鲑鱼

老狮子与大鲑鱼是电影《金色池塘》中的两个比喻。这部伟大的电影,有很多可以谈论的话题,比如她获得了当年(1981)的最佳男主角和最佳女主角(同样的电影我现在只想得起As Good As It Gets);这是亨利方达获得的唯一一次最佳男主角奖,虽然他是最伟大的演员之一;这也是亨利方达与女儿简方达唯一合作的一部电影,在电影中他们饰演暗战多年的父女;这部电影也结束了现实生活中,亨利方达与简方达的暗战关系。
亨利方达与凯赦林赫本在这电影中饰演一对老年夫妻,丈夫80岁,妻子69岁。虽然两人一起获奖,但是在我看来,赫本在这部电影中的表现也只能算是不错,而亨利方达的表演却是放在整个影史中来看,也是非常出众的。他成功地表现了老头子Norman的恐惧、好强、自负、自强,多种性格在他的身上集中体现,却又非常的和谐。
亨利方达在出演这电影的时候,已经重病缠身,带着心脏起搏器在演戏。想起来,他泡在水中的那段戏,真不知道是怎么拍出来的。在拍这电影的两年前,亨利方达获得了电影学院颁发的终身成就奖,可始终没有得到他最想要的最佳男主角奖。这个迟到的最佳男主角终于在1982年的春天来了,这时的亨利已经卧床不起了,是他的女儿简方达替他领奖,半年以后,亨利就去世了,这是他的最后一部电影。
亨利方达在荧幕上的形象一半都是非常正统的,但是在生活中却绯闻不断,他一生中有五个妻子。简方达的母亲只是他妻子中的一位,还是自杀而死的一位。亨利在不到一年之后,就娶了新太太。可以想像简方达和父亲的关系如何了。即使在简方达成名后,这两人关系一直很僵,互相攻击。在亨利方达老了以后,简方达却开始慢慢谅解和理解了父亲。《金色池塘》是这父女二人合作的唯一一部电影。
亨利在《金色池塘》中饰演一个80岁的老教授Norman,他曾经机敏博学好胜而且强壮,他喜欢用自己的智慧来作弄对方,让对方不知道如何应答;然而随着年华的逝去,死亡的阴影越来越浓,更让他害怕的是他的能力也在远去,记忆力衰退,体力下降,在熟悉的环境中也会迷路。他真的很害怕,可是他的自尊好强却不允许他被人怜悯。所以他在除了他夫人以外的其他人面前,绝不露出一丝软弱的痕迹,相反的,他比过去更爱嘲笑别人,更爱炫耀自己。在犯错的时候,他会迁怒周围的人,大吼大叫。
他的夫人说,他是一只老去的狮子,他只是在对自己吼叫,告诉自己,他还能吼。
金色池塘中有一只大鲑鱼,强壮而且机智,Norman一直想要钓到他,可几年来,他失去了好几次机会,始终未能得手。这让冬天的老狮子愤怒,也许还有害怕。他的生命已经不多了,他不知道自己是否还能战胜这个最后的对手。生命中的缺憾,是否还来得及弥补?
亨利方达在这电影中已经非常苍老了,但在他的脸上还能看到他年轻时的模样,他在《十二怒汉》中的样子,那是历史上最伟大的电影之一。在这电影中的方达几乎是个完人,聪明机智敏捷,在压力之下依然非常坚定,理智地怀疑同时又是非常的愤怒,愤怒于对正义的伤害。亨利方达还出演过《最长的一天》《正午》《西部往事》等等,可是这些都没有帮他获取那个他最想要的小金人。
在三十年后,《金色池塘》中,亨利方达完全的老了,他表现着自己的衰老、恐惧还有愤怒。这一次,他终于钓到了自己的大鲑鱼。

2005年1月9日星期日

几张照片

昨天夜里,我从公司出来的时候已经过了12点。外面正飘扬着纷纷扬扬的雪花,在蕴黄的路灯下,怡然自得。我想明天大概能够拍到雪景的照片了吧。
可是今天早上醒来后,却发现室外看不出一点下过雪的痕迹,雪化入梦了。
到有点想念北京小河沟上一个冬天都化不开的冰层。
不管如何,还是在早晨跑步的林间小道上拍了几张照片。连接前两天拍的几张一起上传了。点击查看:Country Road

2005年1月7日星期五

Rosemary

今天听到了《毕业生》的OST,Simon & Garfunkel包办了整部电影的配乐,其中有三首非常流行的歌。Mrs Robinson,Sound of Silence和Scarborough Fair。
电影《美国派》中有个家伙和同学的母亲有亲密关系,他们两个出场的时候,总会配上Mrs Robinson的音乐,这就是来自《毕业生》的典故。
Sound of Silence大概是这三首歌中最有名的一首。
不过我最喜欢的是Scarborough Fair。
第一次听到这首歌是高三的时候,吉它、和声、多音轨、晦涩的歌词,当时感觉犹如听到了自己的主题曲一般。我找了盘磁带,两面全都反反复复的录上Scarborough Fair,放在随身听里面连续不听的播放,Parsely sage rosemary and thyme...She once was a true love of mine。
那个夏天,我就一直坐在书桌前,汗流浃背,一边准备高考,一边听着Scarborough Fair。
到现在,当我听到这首歌的时候,首先想到的不是那个叫Elaine的女子,而是一个明晃晃的夏天。

在网上查找有关Scarborough Fair的时候,竟然找到了莲波在ACT上发表的一组文章。小生是晚辈,ACT是从未见过的啦,而当年ACT上的名人,现在依然活跃着的恐怕也只剩一个方舟子了。莲波的名字在网上还能偶尔见到,那是因为她当年游戏文字,翻译了一个Scarborough Fair的古文版歌词。而Scarborough Fair的生命力当然要比网上的马甲强多了。可以想像,当Scarborough Fair还在世间传唱,莲波的名字就会随着她的译文继续在网上流传下去。

这个链接里是莲波的一些文字,放在新语丝的服务器上,估计从大陆是访问不到了:http://www.xys.org/xys/netters/Lianbo/prose1.txt

后面,我会贴上莲波的《伪造诗经》;蓝极写的《Scarborough Fair中的解读》 ;和弓枚写的《"斯镇的颂歌"详解》。前两篇都很有趣且篇幅短小,不妨读读;最后一篇的篇幅就大了,但是读了也颇长见识。

〖转〗伪造诗经 from 莲波
〖转〗Scarborough Fair中的解读
〖转〗"斯镇的颂歌"详解

2005年1月1日星期六

〖转〗走近真实的杨振宁


走近真实的杨振宁
◎鲁伊
2004年12月30日三联生活周刊

以82岁之身迎娶28岁的女研究生,2004年底爆出的这条新闻,使杨振宁一下子成了全球瞩目的新闻焦点。且不说新浪网上数以万计的留言评论,就连大名鼎鼎的路透社、美联社,也借此机会,八卦了一回。
有人说,杨振宁已经成为一个中国成功男性的符号:生于学术世家,学术上,35岁就得了诺贝尔奖,自此成为一代宗师;政治上,地位超然,历代领导人都礼为上宾;生活上,妻子杜致礼是大家闺秀,子女双全且均事业有成,到了耄耋之年,又有"上帝恩赐最后的礼物"……
但符号从来都不是全部的真实。今年早些时候,在人民大会堂举行的"2004文化高峰论坛"上,杨振宁题为"《易经》对中华文化的影响"的演讲,经网络和大众媒体的辗转相传,成了一场中西符号大战。具讽刺意味的是,仔细探究之下,你会发现,在这场大战中,声音最响亮的那群人,既不知道杨振宁到底说了些什么,也不知道《易经》说过些什么。同样的事情在几个月后重演。很多人都知道杨振宁是"著名华裔物理学家、诺贝尔物理学奖获得者",但他究竟做过些什么,是个什么样的人,却很少有人清楚。但其实,只有把这些弄明白,你才可能会明白,为什么会有这样的杨振宁,这样的中国科学界,这样的故事……
1922年10月1日,杨振宁出生于安徽合肥。因他父亲当时正在安庆一所中学教书,安庆又名怀宁,故此给长子取名振宁。
杨振宁的父亲是杨武之。现在说起这个名字,已经很少有人知道。但半个多世纪以前,在学界提到杨武之,真是"天下无人不识君"。杨振宁才10个月大,杨武之便考取安徽公费留学,前往斯坦福大学学习,随后在芝加哥大学数学系师从著名数学家迪克森(L.E.Dickson),成为中国第一名因数论研究获得博士的学
者。归国后,杨武之在清华大学担任算学系(后改称数学系)教授和系主任长达20年之久,陈省身、华罗庚等均出自他门下。华罗庚曾写信给杨武之道:"古人云,生我者父母,知我者鲍叔,我之鲍叔乃杨师也。"
生长在这样的家庭中,杨振宁的早慧很早就被发现和善加引导。杨武之教儿子天文、物理、数学、英文、唐诗宋词、易经八卦,为他延请的家教,也均是当时清华燕大名师最得意的门生。在清华园和燕园中,"杨武之之子"成为许多教授教育子女的榜样。
迄今为止,共有6名华人曾获得诺贝尔物理学奖。探究他们的身世,你会发现一个非常有趣的现象。丁肇中的父亲丁观海,早年留学美国,是臧克家的同学,山东大学著名教授。李远哲之父李泽藩是著名水彩画家,台湾新美术运动先锋之一。朱棣文是著名化学家朱汝瑾之子,母亲李静贞也是负有盛名的化学家。只有
李政道和崔琦,出身贫寒,但他们的成功,也多赖吴大猷、吴健雄等名人之后的提携。
这种世家的力量,在生于20世纪早期的科学家群体中,表现得非常明显。举国烽火,中原板荡,只有世家子弟,才可以奢侈地躲进学术世界自成一统。1945年8月29日,23岁的杨振宁从昆明飞往印度,然后乘船过红海、地中海和大西洋,来到纽约。从哥伦比亚大学到普林斯顿,再到芝加哥大学,辗转反复,杨振宁才
最终找到战时因为参与原子弹研制工作而行踪被保密起来的物理学大师费米。经费米推荐,杨振宁得以成为美国氢弹之父特勒的学生。
杨振宁在芝加哥大学最初的研究工作并不太顺利。虽然师长们对他的见识非常欣赏,但缺乏动手能力却成了杨振宁的死穴。他自幼便是左撇子,好不容易才被母亲纠正过来。关于他的笨手笨脚有个笑话:杨振宁小时候曾用泥捏了一只鸡,拿给父母看,杨武之夫妇为了鼓励他,夸奖说:"这支藕做得真不错哦!"而在芝加哥大学,"哪里有爆炸,哪里就有杨振宁"的笑话,更是一直流传至今。
1948 年初,获知杨振宁在实验室不顺经历的特勒给出了建议:转攻理论物理学。
杨振宁在西南联大师从吴大猷做分子光谱与群论研究时 ,采取的是推演法,即从数学推演到物理的方法。而在特勒门下,主要的研究法却是归纳法,也就是从物理现象引出数学表达的方法。对研究方法的掌握被杨振宁视为早期学到的最重要一课。正因为有这些当年的经历和经验,50年之后,杨振宁才会在人民大会堂侃侃而谈:以《易经》为代表的中华传统文化有归纳法而无推演法,是近代科学没有在中国萌生的原因之一。
1949年春,杨振宁前往奥本海默主持下的普林斯顿高等研究院,从事量子电动力学研究。在这里,他遇到了自己未来的妻子杜致礼。
杜致礼是杜聿明的长女,与杨振宁相识于西南联大,曾是杨的学生。虽然曾为权倾一方的高官之女,但此时,杜聿明在淮海战役中战败被俘,杜致礼的学费也就没了着落,只好打工维持学业。1949年圣诞节,杨振宁和普林斯顿的同事、物理学家鲁丁格(J.M.Luttinger)到中餐馆"茶园餐厅"吃饭,邂逅杜致礼。相逢于患难之时,两人很快就谈起了恋爱。1950年8月26日,杨、杜二人在普林斯顿结婚。两人育有二子一女,携手度过53年的人生风雨,直至杜致礼于2003年10月因病去世。
杨振宁翁帆订婚的消息传出后,有家北京媒体登出了一篇《吴大猷与爱妻终生厮守》的文章,一半内容倒是凭空的臆测。一位台湾物理学家对记者说,上世纪60年代,往返于加拿大和台湾之间讲学的吴大猷,曾瞒着妻儿在台湾收养了24岁的义女吴吟之,一度闹得满城风雨。直到80年代,吴吟之的身份才被公众所知。
1998年,吴大猷曾送诗给吴吟之:"把断线风筝拴在地上,使其能高扬的吟之,有你的地方就是我的家。"虽然议论纷纷,但在学界却也是一段佳话。换成今日大陆的杨、翁,却不知为何成了窥私的狂欢,令人慨叹。其实,像吴大猷、陈省身这样的大师,当年都是风流倜傥的翩翩佳公子,远不是几十年来僵化语境下的"上大人老夫子"。而学者的声色犬马之欲、爱恨情仇,皆是私事与个人选择,又和他们的贡献、身份有什么必然联系呢?
提到杨振宁,一个不可忽略的名字是李政道。从1946~1962年,两人的合作长达16年,曾经焦不离孟,孟不离焦,同出吴大猷和费米门下,因宇称不守恒理论永被后世学者铭记,同获诺贝尔奖,最后却断然决裂,数十年虽对面而如陌路,不能不谓遗憾。
李政道比杨振宁小4岁,生于上海,在西南联大读大学二年级时,经吴大猷推荐进入芝加哥大学当研究生。当时,杨振宁在芝大已经是小有名气的"学生老师",李政道却还是"后学小子",杨振宁对李政道的帮助甚多,以至于后来回忆道"在芝加哥的岁月里,事实上我倒成了他(李政道)的老师"。1951年,在杨振宁的建议和帮助下,李政道前往普林斯顿高等研究院做博士后研究,两年后又转去哥伦比亚大学。两人一直保持每周定期的互访。
从 1954~1956年,杨、李二人都在关注后来将他们推上成功巅峰的宇称不守恒问题。1956年4月初,第6届国际高能物理会议在罗切斯特大学召开。杨已是第5次参加这个会议,在最后一天的讨论会上应邀做该问题的介绍报告。第一次参加该会议的李政道也参与了讨论,物理学家费曼和布洛克还同他交流了一些看法。一个月后,杨、李二人就提出了宇称不守恒的假说。
对于是谁最先迈出了关键的一步,杨、李二人各执一词。作为外人,没有探知真相的可能,也没有这样的必要。我们只知道,这一年5月,本来计划前往日内瓦参加学术会议的吴健雄因为深知此事重要,留下来与美国国家标准局的4位物理学家进行了检验实验。1957年1月9日,实验结果证明了杨、李假说的正确性。
杨振宁在美国物理学会年会上介绍这一成果时,会场爆满,以至于有人甚至"爬上了吊灯"。宇称不守恒定律是如此的重要,一向矜持的瑞典皇家科学院也打破了常规,不到一年就把物理学奖授予两名年轻的中国人。
就在两人的声望如日中天之时,不和的阴影却也开始弥漫开来。未出名时,论文的排名或许可以风水轮流转,但成名后,尤其是论文的重要性开 始凸现出来,争执却变得无法避免。这种争执在1962年随《纽约客》上的一篇文章到达顶点,这年夏天,两人公开决裂,"永远分手"。
杨振宁和李政道的恩怨,在许多人看来,无非是"学院里的分赃不均",但事实可能并非如此。杨、李后来都有多次与他人合作的经历。杨振宁三大成就中另外两项——杨-米尔斯规范场理论和杨-巴克斯特方程,也是与人分享,但却没有蹈杨、李之争的覆辙。
其实,这种不和,或许可以从更久远的过去中找到解释。无论是世家还是贵族,它们的力量和魅力,都在于可以超脱于凡世,维持一个自我的外人无法轻易进入的小圈子。在贵族式微的时代,转向高深的不足为稻粱谋的学术,成为许多最后的贵族的选择。所以,会有袁家兄弟、吴家兄弟、陈省身、杨振宁……身为圈外人的华罗庚、李政道,不可能不与圈子中的人发生接触,但却又无法越过那道看不见的障碍。那种发自内心的沮丧与失落,同今日网络上因杨、翁订婚而引发的俗世百相,大约并无本质的区别。