[ASP.NET入门随想五] 金庸群“粒”传
—— OO思想的对象与类


        几年前一位名叫姚壮宪的失恋青年编出的李逍遥红遍大江南北,他那现实无法实现而杜撰出的一夫多妻艳运让我家奔一电脑天天被几个朋友轮流折腾。刚有些平静,智冠又把《金庸群侠传》摆上摊头,于是我那可怜的奔一又开始拖着疲倦之身不停地劳作。据不完全统计,我家的键盘在95-96年度内换了不下十次,为了减少损失,我不得不为电脑销售商充当免费"伊"拉克角色。

  仙剑胜于情节,金庸优在开放。所以仙剑必然用大力气去渲染故事的传奇性,于是多角爱情、天地人三界、魔法武功尽数登场,同时着重刻画故事的背景情境,画面优美、音乐动听、动画生动,搅得你是身临其境、如痴如醉;金庸群侠传的灵感来自于风靡一时的网络MUD,于是出现了一种多线索、多结局的新武侠游戏模式,或正或邪,或剑术名家或内功高手、东南西北,给了玩家充分的自由度,让你禁不住高呼freedom。

■ 左手画圆,右手画方 - 面向过程编程思想的命门

  尽管《高级语言程序设计》课程早就是大学的必修课,但众多学生也许终身也弄不明白,这个世界怎么就变成算法+数据结构。

  数学家出身的冯·诺依曼设计出来的计算机体系结构正如他草稿纸上的数学公式,过程明确,有序推演。在这种机器模型前提下,早期程序员们的面对过程编程思想显得顺理成章。于是一代又一代的后继者为了利用计算机解决现实问题,不得不把问题分解成一个个精致的过程模型,映射到机器模型中,他们梦想能和李逍遥一样,能走出一条精彩之路。



  但我们不得不承认这种思维模式的确与众不同。人认识这个世界,首先从名词开始,"妈妈"或"爸爸"往往是每一个人开口说的第一句话,只有认识积累到一定程度,我们才可能有意识地把某个领域的所有名词用动词联系在一块,形成一个完整的处理流程,谓之过程,可见人对过程的认识需要时间。与之对应的矛盾是,面对过程程序员工作的前提是--需要一个正确的过程模型。更遗憾的是,即使是一个完全正确的过程模型,它也在不断地变化,而且变化的速度在目前有愈演愈烈的迹象。

  过程通常又是独特的,悲痛孤独的姚壮宪杜撰出精巧的《仙剑奇侠传》,美女满怀的姚壮宪策划出平淡的《仙剑奇侠传2》,人类活动不可能都象数学公式一样,有一个统一的推演过程。与之对应的是,作为过程的抽象--函数,不可复制几乎成了其根本属性,那么由一个个函数组合而成的程序再谈什么软件复用似乎就象海市蜃楼般虚无飘渺。

  人脑通常只能一心一用,所以很难同时左手画圆右手画方,这是众所周知的事实。但许多面对过程程序员却一直在做着许多看似荒谬的事情--用序列化的方法来模拟多任务的处理,即左手画一段弧,右手再画一条边,不断重复这两个动作,只要动作足够快,他人的感觉就是你一心二用。我们不得不叹服其精巧之至,但同时也不得不承认其繁杂。而过于繁杂的东西,其成本之高可想而知,当这个世界的每一个时刻都在各个领域发生着大量事件时,试问这种精巧的处理方法将变得何其脆弱。

  冯·诺依曼设计出来的计算机体系结构有先天性缺陷,但让计算机界现在就完全推翻整个体系不现实,于是便有了改进,有了分工。

■ 九九归一 - 面向对象思想的对象世界

  我的《金庸群侠传》玩友石头有些与常人不同的习惯:看人时,并不关注这人的外形,而是关注他的生命值和攻击力;谈话前,常会下意识地用大姆指在空中狠狠按一下;进入一个陌生的屋子后,石头的目光通常会先投向柜子和抽屉,生怕遗漏里头的药丸。

  很多人描述自己的《金庸群侠传》传奇时,常会以"出茅屋、进河洛、到南贤……"之类的话来开题,洋洋洒洒说上半天,欧阳克野球拳宝济丸之类夹杂其中,让人不禁对其博学多才油然而生敬仰之情,可回头咀嚼,却依稀只记下几个名词。一向崇拜cantor的石头是这么描述这个世界:"一块蛋糕,点缀着几个草莓,一只蚂蚁在其中往返,并不时地钻到草莓里头看看。"

  《金庸群侠传》给我们带来的第一映像是充斥着各种各样的粒子。我们将会遇到客栈老板、欧阳克等人物;将会得到宝济丸、岚氏乌鸡精等物品;将学会辟邪剑法、左右手互搏术等武功;将钻进少林寺、武当山等地。涉世之初,它们混沌地夹杂在一起。

  这些粒子有各自的特征和行为,如小虾米有攻击力、防御力等数值来描述他的当前状态,可做行走、服药、对话、决斗等动作来影响自己或它人的状态。我们将所有粒子统一命名为对象(object),用图5-2右描述,并可将所有的对象定义成一个集合,如图5-2左:

 

  一一列出所有的对象太麻烦,而且许多对象极其相似,所以我们可以用集合的等价划分方法(图5-3左)来简化描述,并用类(class)来刻画划分(金庸群侠对象集合的子集),如图5-3右,实际上我们可以发现,类本身就是一个集合,这个集合的元素是相似对象的公共状态和行为。

 

  这个从归纳到演绎的过程是面向对象思想的核心:首先用类来刻画所有相似对象,完成从多到少的抽象过程,化繁为简;使用时通过类派生出实例,完成从少到多的构造过程。实际上这就是cantor朴素集合论化潜无限为实无限的思想。

  我们再来看看有趣的类。首先它要求别人尊重它的隐私,隐藏一切与其他对象无关的属性和方法,如对于平一指而言,他不能控制小虾米的行走,也不知道小虾米是如何完成行走这个行为,我们把这种特性称之为封装,小虾米用private和public关键字控制自身描述是否向外界开放,这是软件开发工厂模式的基本前提。实际上在以后的章节中我们可以发现目前实际应用倾向于尽可能地封装类的属性和方法,而通过其它方法来完成访问类。

  再则类的方法(method)善变,谓之重载,是面向对象思想多态性的一种情形。重载是对相似方法的抽象,善变的目的是为了让方法变得更简单明了。以人物类的服药方法为例,宝济丸加体而岚氏乌鸡精加精,其效果不同,传统办法是使用大量SWITCH或IF嵌套来实现。而现在可以修正如下,发招方法同样可以重载。对类的外界而言方法名是唯一的,但实际使用过程中系统会根据参数自动调用不同实现:

Class 人物
{
  private 生命力;
  private 精气; 
     ……
 public 服药(宝济丸)
{生命力+=3;}
 public 服药(岚氏乌鸡精)
{精气+=5;}
 ……
}