6
接下来很自然就是面向对象之旅了。接受了C++,Java的洗礼,平时也喜欢逛逛论坛,如果一个人不至于太愚笨或者顽固,肯定会被铺天盖地的摇旗呐喊所感染。当然,自认为自己还算是脑子灵活而且思想开明的,于是OO神殿下又多了一个顶礼膜拜者。这年头,如果不捣鼓几下OO,你都不好意思说你是个程序员 :)。
觉得需要学习一下OO理论是在编了一些稍稍大点的程序以后,那时感觉类与类之间的关系总是难以把握,什么时候继承,什么时候多态总是茫然不知所措。突然发现自己以前就是一个认字的,知道了class,object,inheritance,polymorphism一大堆概念,却不知道如何有效地把它们组织运用,根本算不得文章。
学习过程颇为艰辛,先是在网上翻阅了一些文章,然后硬肯Booch的《Object-Oriented Analysis and Design with Applications》,奈何当时代码量不足,根基又浅,除了了解到一些基本概念以外,并无多少实际收获。
随后开始接触设计模式,GOF的《设计模式》和Metsker《设计模式Java手册》是我最开始的旅程。万事开头难,书中很多话语都没能好好理解,但终于对设计模式还是有了一个稍微全面的了解,也当作是一个认字的过程吧。有人说没有10万行代码的积累最好不要碰设计模式,但我觉得凡事都是一个循序渐进的过程,不可能说突然到了某一个点,以前从不知晓的东西会豁然开朗。可能有大量代码基础去看设计模式去起点要高一点,或许会少许多烦恼。但是我们也不妨先作了解,然后在代码的积累过程中慢慢领悟,一起成长,这样等自己有十万代码时体会会更深。
个人觉得学习模式的最好的方法是在开源项目的源代码中追寻模式的踪影,这既能提高代码阅读的速度和质量,同时可以帮助理解模式的妙用,一箭双雕。Sourceforge上面优秀的开源代码数不胜数,涉及方方面面,实现也各色各样。对于学习模式,我个人觉得Java比较合适,因为它相对简单,不需要在代码处处理跨平台和内存管理,比C++等语言相对清晰很多,不至于因形害意。在学习过程中,有时我们会把两者搅和在一起:学习OOD的时候陷入了具体语法的泥潭中;学习OOP时却又过分追求设计技巧。于此,Kent Beck的“两顶帽子”思想同样是有用的:我们必须清楚现时的关注点是什么,OOD还是OOP。
后来,因学习研究的关系读了Douglas Schmidt的《Pattern-Oriented Software Architecture, Patterns for Concurrent and Networked Objects》(也就是 POSA2)和Alan Shalloway《设计模式解析 2ed》,触动都很大。后者给我耳目一新的感觉,强烈推荐。
正如Erich Gamma所说,关于模式的书都不是读完一遍就可以束之高阁的。我们需要在软件设计过程中反复理解,这样每一天都会有新的理解,新的体会。还是那句话,“走”“停”之间,彰显智慧,有时对一个问题束手无策,可能只是和它缘分未到,随着知识的积累,某天它的答案就突然跳到你面前了。
我也知道,一个系统是否OO其实并不重要,软件开发过程中所有人都只有一个目标,就是如何“多快好省”把软件生产出来,甲方可以顺顺利利提高生产力,乙方可以高高兴兴提高生活水平,就OK了。工具嘛,管它白猫黑猫,能拿耗子就是好猫,小平这句话实在精彩。平时,论坛上充斥着太多的口水战,Windows和Linux阵营互不相让,Java和C++两派大打出手,现在Ruby一方又大张旗鼓。交流讨论很好,但形同水火却大可不必,工具是拿来用的,只要自己喜欢,又确实可以帮助自己完成预订目标,孰好孰坏,who cares?
OO一词是Dr. Alan Kay在 60年代提出来的,喜欢追本溯源的可以看看创始人对这个词的诠释。但二十多年来,OO一直默默无闻,直到九十年代,才开始在世界范围内流行起来了。大量系统开始使用OO方法进行构造,支持OO的工具也不断出现,两者相互促进,使OO空前繁荣起来。事实也表明,OO确实能够提高软件开发的生产力,虽然并不是传说中的银弹,但确实是一只能够逮住耗子的好猫。
软件之殇在于“变”。软件直接面对的是最终用户,一群活生生的人,而人可能是这个星球上最善变的动物了。需求分析时功能定不下来,等某天他咬紧牙关定下来的时候也就意味着“变”;某天突发奇想,需要增加新的功能,“变”随之而来;项目接近尾声了,已有功能突然需要来个大变脸,变变变!如果所有东西都可以一开始就定下来,并且永不改变,那么使用哪种软件开发方法并不重要。但是,The only thing will not change is variety,与其被动逃避,得罪我们的衣食父母,不如积极去拥抱它,随需而变。
OO的出现,能够很好的捕捉这一系列的变化。封装是OO的本质特征,这既包含了对数据的封装,也体现在对类型的封装上。前者是古典面向对象理论对封装的诠释,而后者的提出使得封装的概念更加完整。封装的出现,使系统中各个部分如果能够做到各自相对独立,可以有效隔绝局部变化对系统整体造成的影响,这对于一个大型复杂的系统而言是极有价值的。现实世界也是如此啊,以前地球人丁稀少的时候,人就可以随意迁徙,国界概念并不明显,也不会造成多大的影响。但如今人满为患,各国只好加强人员进出的控制,海关、签证等制度也应运而生。现在,出个国又是护照又是签证的,去和领事先生打个照面就被收取$100,封装得也够严实了。
此外,要想实现“多”和“快”,软件复用是必不可少的。软件就有这一特点,一个模块可以身兼数职,但是并不增加成本,这跟硬件可是大不相同,硬件的成本可是跟这个“数”直接成正比关系的。但是这个特点也会带来烦恼,大家都在用同一个模块,结果相互影响,最终连正确性都不能得到保证。如何做到“克服缺点,发扬优点”,正是软件复用的研究范畴。OO中通过“继承”、“包含”、“使用”等概念实现了元件间相对独立的代码复用,而框架,组件等系统复用的出现把软件复用提升到更高的层次。
可维护性和可扩展性也是软件开发经常提到的宏伟目标之一,而这两者都是基于对已有代码的深入理解之上的。咋眼看来,对于OO,这点其实蛮有争议的。面向对象一个很大的特点就是存在很多委托关系,一件很简单的工作,往往是A委托给B,B又委托给C,我们看源代码的时候得跨越千山万水,历经N个源文件,最后才能看到那个实际的worker。相比之下,面向过程的语言倒来得直接很多。
但是,如果系统最初的设计者能够把自己的设计思想有效地传递给后续开发者,维护人员以及二次开发人员,那么我们的后续工作要轻松得多。这里,不能不提设计模式(Design Pattern)。设计模式这个概念最初由Christopher Alexander在建筑领域提出来,而GOF(Gang of Four)于九五年出版的《Design Pattern》一书将这个概念引入到软件开发领域。据我的理解,设计模式就是在特定上下文中某个特定问题的特定的行之有效的解决方案。设计模式的出现,一方面使得OO的设计技巧不仅仅只是存在于个别大师的脑海中或者埋藏于一堆堆令人畏惧的代码中,而是具体现象地展示在设计者面前,给与设计者良好的启示。另一方面,设计模式如同在OO世界中引入了一门“世界语”,各方人员在讨论OO系统时,不再需要繁杂的类图,不再需要解析A继承了B,C使用了D。我们只需说,这里使用“工厂模式”,一切就一目了然了。当然,这些都是需要付出代价的,开发小组中各个成员必须都对设计模式十分了解,否则,只会出现“鸡同鸭讲眼碌碌”的尴尬。
懂得了设计模式,OO系统会更加容易理解。Erich Gamma通过讲述JUnit的设计给我们展示了这一过程。一个好的设计,加上一份好的说明,阅读代码不再是痛苦的历程了。
7
工欲善其事,必先利其器
Eclipse是我最喜欢的IDE,诸多原因吧:免费、开源、开放、对Java近乎完美的支持、漂亮友好的界面……真是“Gamma一出手,便知有没有”。
我一直不喜欢大包大揽的开发环境,虽然功能强大,但是繁杂臃肿,让人不知所措,而且还非常强势,侵略性十足,捆绑了一大堆它认为十分有用的工具,宣称“看,我有这样的功能,你可以这样用,但也只能这样用了”。往往为了使用这个IDE,必须把它的那套方法学也全盘接受。Faint,是我在用你还是你在用我啊。套餐服务,光中国移动的就够我们受的,就不用你来掺和了。
相比之下,Eclipse 就温柔得多。它采取一种截然不同的哲学,只提供一个开放性的框架,其它功能都是以插件的形式提供的。如此一来,大家可以各取所需,自由定制,见到的都是我们日常需要的工具,而那些这辈子可能永远都不会用到功能从此消失。眼不见为净,这下心里舒服多了。萝卜白菜,各有所爱,思想不再受奴役,心情也会好很多,生产力自然也就上去了 :)。
Eclipse理论上只是一个大容器,虽然本身已是一个出色的Java开发环境,但能否做到按需定制,全赖于plug-in的数量和质量。好在Eclipse社区的活力莫容置疑,从可视化界面开发到J2EE开发环境一应俱全。现时品种繁多,功能齐全的plug-ins足以满足我们绝大数人的需求。此外,一些大公司加入到Eclipse基金中,也推出了自己定制的基于Eclipse的IDE,如Nokia最近就发布了Carbide,用于Symbian 程序开发。这对于我们程序员无疑是一种福音,因为我们可以在一个统一的环境下编写各种程序,不会每次都要面对一张陌生的面孔。
Gamma作为Eclipse的总架构师,编写plug-in也是不甘人后。他跟Kent Beck在30000英尺的合作的产物JUnit已经内置到Eclipse中去。通过它,我们进行单元测试要方便的多。
CVS/SVN和MS的VSS的代表了版本控制两种不同的方法学,我更喜欢CVS的方式,也觉得更为有效,可能是自己参与的项目都比较小,跟人同一时间编辑同一个文件的几率比较大的缘故吧。况且Eclipse对CVS提供了良好的支持,对我而言说服力已经足够了。其实这还有个好处,现在许多开放源代码都是通过CVS来管理的,熟悉了CVS,无疑是掌握了打开保障大门的钥匙。SVN作为CVS的同门师弟,诞生的使命就是要克服CVS存在的种种不足,当然值得期待。
如果说Eclipse等IDE堪称开发工具中的航空母舰的话,那么EditPlus应该就是那把瑞士军刀了。EditPlus是我平时用的最多的文本编辑器,简单,轻便,但是功能强大。它几乎可以编辑所有常用的文件格式,如C/C++,Java,XML,Perl等。同时我们还可以通过自定义添加工具把它变成一个微型IDE。通常我会把javac和java放到工具组里面,这样编写一些dummy test时,就不需麻烦Eclipse这位老兄了,等它启动完毕,可能我都搞定了。如果要查看文本十六进制编码,那么UltraEdit是一个不错的选择,像研究字符编码的时候可能要经常用到。
《程序员修炼之道》,这是一本书,但我想在这里把提出来,因为它让我体会到了“取”之以鱼,不如“取”之以渔的道理。很多程序员心胸过于“伟大”,“一心为人,毫不利己”,每天都在为提高别人的生产力而废寝忘食,却从来未曾为改善自己的工作状态做过丝毫努力。我们能够熟练地使用工具,同时也能快速的创造工具,程序员就应该有这样的能耐。这是我决心开始学习Python的重要原因。通过这些脚本语言,我们可以很快构造出满足自己需求的小工具,譬如文本处理、抓取网页、整理小型词库等等。
上面说了Eclipse那么多好话,也享受了plug-in给与的诸多好处,下一步我准备尝试写一个自己的plug-in,就算只有自己用也是好的,加油吧。
8
庆幸的是我,一直没回头,终于发现,真的是有绿洲。
---信乐团
李教授给我们讲过广度和深度的辩证关系,说平时应该注重开拓自己的视野,寻找自己的兴趣所在;认准之后用心钻研,努力突破;到达一定深度后,交叉互联,融会贯通,整个过程就如同在书写一个“工”字。
前面那些日子,在计算机科学这个大观园中走马观花,其中美妙,让我流连忘返。但是,总不能永远浅尝辄止下去吧,也该静下心来,好好钻研,书写“工”字那一竖的时候了。
网络对我有着一种莫名的吸引力,觉得一行行孤立的代码只要通过网络这根纽带联系起来,总能迸发出闪亮的火花。现在做的东西,的确是我喜欢的,也是我想踏踏实实把它做好的,这就足够了,我也希望它能成为那一“竖”美好的开端。
每个敢于追逐自己理想的人都是可敬的,希望大家都能找到属于自己的绿洲。也谢谢理解我和支持我的朋友们。
(End~)