隐喻的重要性

要的研发成果经常产自类比( analogy )。经过把你不太理解的东西和一些你较为理解、且十分相似的东西作比较,你能够对这些不太理解的东西产生更深入的理解。这种使用隐喻的方法叫作“建模( modeling )”。
科学史中处处均可以看到借助隐喻的力量而产生的新发现。化学家凯库勒曾梦见一条蛇咬着本身的尾巴,醒来后他意识到相似的环状分子结构正好可以解释苯的各类特性。后来的进一步实验证明了他的这一假说( Barbour 1966 )。
气体的分子运动理论则是基于一种所谓的“撞球( billiard-ball )”模型,它把气体分子想象成有质量且彼此之间发生弹性碰撞的小球,就像撞球同样。有不少有用的理论就是基于这个模型提出来的。
而光的波动理论则主要是在研究光和声音之间类似性的基础上发展起来的。光和声音都有振幅(亮度、响度)、频率(颜色、音调)和其余一些共有属性。对声波理论和光波理论进行对比研究的成果丰富,科学家们甚至付诸大量的努力,想寻找一种能在真空中传播光波的介质(就像声波能在空气介质中传播同样),并将这种介质命名为“以太( ether )”——但他们从未能找到过这种介质。虽然类比催生了丰盛的成果,这一次它却把人们引入了歧途。
不过总的来讲,模型的威力就在于其生动性,让你可以把握整个概念。它能隐隐地暗示各类属性( properties )、关系( relationships )以及须要补充查证的部分( additional areas of inquiry )。不过有时候,当隐喻的概念被过分引伸时,模型也会误导人们。当科学家们寻求“以太”的时候,他们就是过分地引伸了模型。
正如你所预期的那样,有些隐喻比其余一些更贴切。一个好的隐喻应该是简单的,它与另外一些相关的隐喻联系密切,且可以解释大部分实验证据及其余已观测到的现象。
来考虑一下这个例子:把一块沉重的石头绑在细绳上让它来回摆动。在伽利略以前,信奉亚里士多德学说的人们看到这个现象时,想到的是重物体天然地从高处坠落,落向低处并静止下来。他们会想,下落的石头遇到了阻碍。而伽利略在看到这个现象的时候却想到了钟摆( pendulum )。他认为,那块石头其实是在不断地重复着几乎彻底相同的运动。
这两种模型的启发能力是彻底不同的。亚里士多德学派的人未来回摆动的石头看做是正在下落的物体,所以会去观察石头的重量、石头被拉起的高度,以及它到达静止状态时所须要的时间。而在伽利略的钟摆模型中的要素就彻底不一样了。伽利略观注石头的重量、钟摆的半径、角位移以及每次摆动所花的时间。伽利略之因此可以发现亚里士多德学派的人所不能发现的单摆定律,正是由于他们所用的模型不一样,这使得他们看到了不一样的现象,提出了不一样的问题。
隐喻在帮助人们更好地理解软件开发问题方面所作的贡献,与它帮助人们更好地理解科学问题所作的贡献同样大。在 1973 年图灵奖的演讲中, Charles Bachman 讲到了由盛行的地心说到日心说的转变。托勒密的地心说模型持续了 1400 年而没有受到严重挑战,直到 1543 年哥白尼提出了以太阳为中心的理论,这个理论认为宇宙的中心是太阳而不是地球。这一个认知模型的改变最终帮助人们发现了新的行星,并将月亮从新界定为地球的卫星而不是一颗独立的行星,它也令人们对人类在宇宙中的地位有了一个彻底不一样的理解。

Bachman 曾经把天文学中托勒密到哥白尼的转变,与 20 世纪 70 年代早期计算机编程方面的变化作了比较。当 1973 Bachman 作这个比较时,数据处理正在从“以计算机为中心( computer-centered )”的观点向“以数据库为中心( database-centered )”的观点转变。 Bachman 指出,过去的数据处理是把全部数据看做流经计算机( flowing through a computer )的连续卡片流( stream of cards )(以计算机为中心的观点),如今则转变为把焦点放到数据池( pool of data )上,而计算机偶尔涉足其中(以数据库为中心的观点)。
今天,咱们已经很难想象还有谁会认为太阳是在绕着地球旋转的。相似地,咱们也很难想象程序员还会认为全部的数据应被看做是一个连续卡片流。在这两个例子里,旧的理论被抛弃后,咱们都以为难以置信——竟然还有人曾经相信过这些理论?更有意思的是,当人们正在相信旧理论时,也一样会认为新理论是那么地荒谬,正现在天咱们对旧理论的见解同样。
在更好的理论出现以前,天文学家由于墨守地心说而屡屡受阻。在计算机世界里面也有相似的状况,以计算机为中心的观点也让坚持它的计算机科学家步履蹒跚,直到以数据库为中心的理论出现。
人们经常轻视隐喻的力量。对前面的每个例子而言,很天然地有人会说:“嗯,恰当的隐喻固然是更有用,但其余隐喻都是错的!”虽然这是一种很天然的反应,实际远非如此简单。科学发展的历史并非一系列从“错误”的隐喻到“正确”的隐喻的转变,而是一系列从“不太合适”的隐喻到“更好”的隐喻的转变,也是从不是很贴切的隐喻到更贴切的隐喻的转变,仍是从在一 个方面暗示人们 到在另外一个方面暗示人们的转变。
事实上,那些被更好的新模型所替代的旧模型也依然是颇有用的。工程师们依旧在使用牛顿力学来解决大部分的工程问题——虽然从理论上说,牛顿力学已经被爱因斯坦的理论所取代。
相对于其余学科而言,软件开发仍是一门很年轻的学科,它尚未成熟到拥有一套标准隐喻的程度。所以必然存在许多或相互补充、或相互抵触的隐喻。某些隐喻相对好一些,而另外一些则比较糟糕。你对隐喻有多理解,也就决定了你对软件开发有多理解。 
与其说一个软件隐喻像是一张路线图,还不如说它是一盏探照灯。它不会告诉你到哪里去寻找答案,而仅是告诉你该如何去寻找答案。隐喻的做用更像启示( heuristic ,启发、试探法),而不是算法( algorithm )。
算法是一套定义明确的指令,使你能完成某个特定的任务。算法是可预测的( predictable )、肯定性的( deterministic )、不易变化的( not subject to chance )。一个告诉你如何从 A 点到达 B 点的算法,不会让你绕路,不会让你额外地通过 D E F 等地方,更不会让你停下来闻闻玫瑰花或喝杯咖啡。
而启发式方法(试探法)是一种帮你寻求答案的技术,但它给出的答案是具备偶然性的( subject to chance ),由于启发式方法仅仅告诉你该如何去找,而没有告诉你要找什么。它并不告诉你该如何直接从 A 点到达 B 点,它甚至可能连 A 点和 B 点在哪里都不知道。实际上,启发式方法是穿着小丑儿外套的算法:它的结果不太好预测,也更有趣,但不会给你什么 30 天无效退款的保证。
驾驶汽车到达某人的家,写成算法是这样的:沿 167 号高速公路往南行至 Puyallup ;从 South Hill Mall 出口出来后往山上开 4.5 英里 ;在一个杂物店旁边的红绿灯路口右转,接着在第一个路口左转;从左边褐色大房子的车道进去,就是 North Cedar 714 号。
用启发式方法来描述则多是这样:找出上一次咱们寄给你的信,照着信上面的寄出地址开车到这个镇;到了以后你问一下咱们的房子在哪里。这里每一个人都认识咱们——确定有人会很愿意帮助你的;若是你找不到人,那就找个公共电话亭给咱们打电话,咱们会出来接你。
算法和启发式方法之间的差异很微妙,两个术语的意思也有一些重叠。就本书的目的而言,它们之间的差异就在于其距离最终解决办法的间接程度:算法直接给你解决问题的指导,而启发式方法则告诉你该如何发现这些指导信息,或者至少到哪里去寻找它们。
若是有一些能明确指导你该如何解决编程问题的信息,编程固然会更容易,结果也更易预见。但编程这门学科还没那么先进,或许永远也不可能那么先进。对于编程来讲,最大的挑战仍是将问题概念化( conceptualizing ),编程中的不少错误都是概念性的错误。正由于每个问题在概念上都是独特的,因此要找到一套能解决全部问题的一通百通的指导规则是很难的、甚至是不太可能的。如此看来,能通常性地知道大体如何解决问题,至少也和知道如何解决特定问题同样有价值了。
那么该如何使用软件中的隐喻呢?应该用它来提升你对编程问题和编程过程的洞察力;用它来帮助你思考编程过程当中的活动,想象出更好的作事情的方法。你不可能看到一行代码并说它违反了本章所描述的某个隐喻。但随着时间的流逝,人们会发现,相对于不善运用隐喻的人来讲,那些使用隐喻来照亮本身的软件开发过程的人,他对于编程的理解会更好,而且可以更快地写出更好的代码。
相关文章
相关标签/搜索