为Andrei的贡献喝彩:纪念凤凰涅磐般充满活力的C++

类别:编程语言 点击:0 评论:0 推荐:

  一年前偶得Andrei Alexandrescu 所著的Modern C++ Design一书,随手翻翻,不禁惊呼“原来C++程序可以这样写的”,这是多年以来我被震撼最深的一次。

  记得若干年前,在书店购得冷僻的C++参考手册一本,FoxBase那时候更流行,C也还有几本书,C++则几乎一本都没有。当时初读之后,也是惊呼“C++是属于未来的C”。那是我第一次被技术所震撼。以前写的程序几乎纯面向过程的,虽然也煞费苦心的规划文件和函数的独立性、可读性,但随着程序规模的扩大,哪怕修改一个小BUG也要心惊胆战的检查不少地方,以确认没出现新的问题。那时候一个想法是在DOS下作一套图形界面系统(有Windows界面的DOS,其目的就是不需要进任何目录又不需要占用基本内存就可以方便的启动一个DOS程序)。今天看起来是个简单的事情,但那时还没有internet可以用,电子档源码完全是0,仅解读PCX、显示点阵汉字、图符编辑器(那时候我还不知道有图标一说)这样外围的东西,就花了我不少功夫查资料和调试程序。而随着菜单、窗口、多种VGA显卡、若干中断服务程序的介入,源代码已经复杂得几乎无法维护了。那时候我曾专门花了近1个月的时间来重新规划名称、切分源文件和整理函数位置(最原始的重构)。从那时候起,我对代码质量变得非常挑剔,虽然其他同学、同事多不以为然,呵呵……但不管我当时怎么努力的使情况好转,但总体而言维护仍然是个辛苦的事情。当我看到C++之后,一切都不知不觉中发生了变化,数据和操作仿佛自动的在我的脑子里组合成了类,而每个类都可以单独管理和维护,我甚至可以对每个对象的功能进行测试(单元测试的雏形)。当时为了BC++ 3.1,我不知道用了多少时间在D版盘目录中搜寻,这也顺便提高了下今天的Google能力;而为了在被保护卡所保护的学校机房里用上它,每次都要耐心的把程序从光盘拷贝到软驱又从软驱拷贝出来安装。然而,能用上了C++的我根本不在乎这些,我是无比快乐的,不但见识了很多新鲜的玩意,而且用C++写程序的感觉就像是以前用大刀长矛的人突然有了先进的火枪,一个个程序、一个个类不断的在手底下诞生……

  快乐并不会持续太久,上大学以后,DOS终于渐渐被走向衰落。不管情愿与否,Internet和windows都把我带到了新的平台上。虽然也在尝试看些MSC和BC3.1 for win的书,但我怀疑那是不是一场恶梦……陌生、庞大、难以理解、诡异的返回值和错误处理方式、长得难记的函数名、多得懒得去数的参数和随便写个最简单的程序就要数百行不认识的代码,这一切让API就像一个泥沼怪物,妄图吞没每个试图靠近它的程序员的耐心和信心。在DOS里积累的所有对中断、绘图、程序框架、计算机控制的知识都被无情的抛弃,我只能像个新生儿和傻瓜一样,看着CorelDraw在windows下面漂亮的运行而自己只有羡慕的份儿。我得承认,MS虽然也时常给我惊喜,但给我的挫折和失望更多。大约到大三的时候(win95时代),终于发现了vc4(很快又来了vc5/vc6)。经过一段DOS./Windows的徘徊之后,终于迈进了windows开发的大门。研读mfc的结构已经变成一种新的嗜好,然而一个doc/view就能让人费解半天,那时候几乎没有一本可以把这个概念讲清楚的书。MFC这个目前看来仍然庞大得足以让人却步的库,用熟了之后觉得还是比用API开发更简单快捷,但不可否认它也带来了更多未知的细节,这让我很不踏实,无论MFC的源码如何袒露在我面前。MFC只让我在作恶梦时夹杂作了一小会好梦,恶梦仍然在继续。相比较而言,在学校的开发项目中,他的邻居vb有很多优点表现了出来,但基于对技术和操作系统本身更深层次了解的渴望,C++始终无法让我忘怀。终于,这个难熬的时间也度过了,windows的API层已经变得日渐清晰起来,doc/view也不在那么怪异和难以理解,随时随地继承一些不是自己写的陌生类似乎也变得习以为常,windows我来了,虽然步履蹒跚……

  这时候另一个让我震撼的东西悄悄的走来,那就是COM……其实COM/COBRA很早就有一些资料介绍过,不过都是概念原理性质的,语焉不详,看那些东西似乎比上一堂政治课更加无聊,估计译者本身也是一知半解吧。当时为了一个毕业论文的小玩意,需要作一个在web上发布一个看三维模型的ActiveX。在清华bbs向几位前辈请教后,我便匆匆开始了一次完全是一知半解的开发。虽然最终完成了这个东西,并模糊的明白了到了虚函数表的层次,但当时更多的是对这个小玩意能在ie和vb程序里运行而感到神器。很庆幸我的导师允许我们自己命题,而最终让我(不太熟练的)掌握了这个新鲜的技术。非常幸运的是,我毕业后马上就结识了公司里的一位编程高手。他是COM方面的行家里手,正是他的倡导和帮助,让我逐渐熟悉和喜爱上这项技术。随着调试问题的经验和对ATL库源码的解读,COM开发逐渐不再是那么晦涩难懂的怪异的东西,甚至没有手册的情况下,自己也能在ATL库中找到解决方案。而后来的一本Inside COM,更让我了解了COM的许多细节和秘密。这时候,脑子里早已把对象进一步剥离出一个个的接口,它们之间只通过这些接口建立联系,原有的对象和类不在存在,全部都换成一个个的小积木块。向下兼容的扩展、可替换的部件、插件机制、多层驱动的软件架构、提供二次开发包,现在这一切都变成很现实的事情,这感觉很不错,我也很乐于看到其他VB程序里可以使用那些我用VC开发和设计的大大小小的组件。

  当STL铺天盖地而来的时候,我并没有被震撼,或者说其实我有足够的心理准备。也许因为ATL库早就向我暗示模板的表达力,也或者是因为兼容性不太好的STL一直不太敢在项目中使用,STL给我的感觉始终远没有C++和COM那样强烈,虽然它是那么优雅而近乎完美的作品。STL强化了我原本很模糊的泛型设计思想,不过我了解它之后就很明智的放弃了像篡改MFC和ATL/WTL库一样去扩展STL库(这一点的正确性在之后一些关于STL的书中得到证实)。不过,需要指出的是,COM之后的很多实践,包括STL和.NET的出现,让我更坚定的抛弃了组件,回归更传统的标准C++阵营。事实上,我更需要程序的源码跨平台运行而不是他们的二进制形式,那些在VB、Delphi中运行得很好的用大量代码写成的组件,会让偶尔去研究wince、symbian和web的我看上去几乎像个白痴。所以,我果断的在内心深处放弃了COM(顺便辞了职),COM将仅仅作为一个shell层次的东西,许多特性表明它并不适合作为一个合适的设计基础。我的程序中很自然的出现越来越多的模板,一个构造精巧的模板类常常可以大幅度的显著缩短我的代码量,我常常捧着航母般庞大的设计,却打算用小渔船有限的代码去实现它。STL很多的基本思想早就扎根于我的心中,我逐渐以为C++的终点就是STL了,以后只会出现一些更大更完整的STL,比如boost……

  STL前后又分别学习了一些关于UML、设计模式、敏捷开发、重构、单元测试的书,并且利用几个公司项目补习了一下java。他们都给我留下了印象,不过这种印象只是印证和深化,谈不到震撼和耳目一新。其中GoF提供了我一种新的规范化的设计样例,明晰的结构和扩展能力让我神往。而久违多年的Java就在这时候重新走近了我:一个足够轻量级的跨平台的c++,让我把原来在体系结构可维护性、跨平台性和API上的精力,大部分都转移到程序性能、数据库结构、通讯协议和负载均衡上(ibm的developwork提供了很多不错的资料)。java是个不错的东西,不过我不会赞美java的语法,不会赞美java的虚拟机和跨平台,更不会赞美琳琅满目的J开头的概念,我更多的赞美会留给java的framework,因为是它救了许多项目的命,而不是其他……然而,贪心的我已经开始考虑怎么能把设计模式应用在我的java项目上,结果是惨痛的,我发现自己每次试图这样作时都几乎注定导致“过度设计”和重复写很多看起来一模一样的代码。我甚至考虑过是不是写一个Wizard来生成java源代码。我也满怀希望的试图过用java作一个通用的gof库,但我后来发现这个实现继续下去将无比丑陋,没有人会喜欢把gof作成那样,更不会有人愿意用它,包括我自己。最终,我决定我必须有节制的应用GoF,于是我仅仅把GoF当做字典和公式,在我需要和其他程序员交流时把它作为一种语言,在暂时还没有足够好的解决方案时把它当做字典和范本设计去查和套用一下模型。我不想让一个完全不可能存在的潜在需求去浪费程序员的大好青春(公司和程序员对此都会为此狂怒)。我情愿去阅读和应用其他“模式化”的成熟库(在没有版权问题存在的情况下),而不是自己去实现一个这样的库。于是,java逐渐变成了所有非GUI项目的默认开发平台。掌握java要比掌握c++容易,我认为这对公司和项目都有好处,因为我不能指望每个人都是C++的专家再进我的项目组,更不能指望滥用C++“把整条腿都炸飞”的情况不会发生在项目中。为了我不至于被项目所拖累,我从心里很喜欢java,虽然渐渐的我发现他变得如同C++一样庞大、复杂、冗余。而渐渐的,GoF也离我远去……至于后来的C#和.NET,我也只草草看了1-2本书。我的兴趣不高,不过作为微软的东西,我无疑是需要热身和了解一下的。我相信即便他们有深远的意义,也不会是在设计思想的变革上,更多会在商业层面……

  Genaric Program之后很快又来了个很酷的名词,就是Generative Program。最初的概念也是如同COM一样,是一些粗浅的理论性的介绍。虽然也听说过一些作品和相关的工具,但是觉得是天方夜潭,太过遥远。我必须承认我前面对GoF、STL和GP的所有观点都很快被一个人和他的作品彻底击败了,那就是Andrei和他的Loki。Loki很小巧,但是他提供了基于策略的设计思想、多种设计模式实现层次的复用、一个轻巧的线程模型、基于产生式编程的继承关系的转化、强大灵活的智能指针……虽然也许Loki的代码在一些人看起来像天书一样,但其实这些代码现代、科学、合理、严谨、高效,不愧其Modern C++ Design的书名。遗憾的是,Loki并不很完整,也不能在一些古董编译器下编译。它更像一个实验品和艺术品,向我们展示了C++凤凰涅磐板的创造性和生命力。谁不渴望一个支持线程安全的STL,谁不想在STL容器内安全的使用智能指针,谁不想在自己的程序中简单的实现多种设计模式,谁不想用多种高效率的内存管理策略灵活的管理对象的生存期?虽然现在还不能预见到什么,但相信loki所展示的技巧和包含的设计思想会影响C++社区,我们很高兴的看到boost库添加了很多Modern的特性,也许Loki会永远都如同他的名字一样作个捣蛋鬼,注定不会成为C++的主角。但我相信会有很多人永远记得Andrei和他的Loki,记得他为C++社区作的贡献。让我们一起期待着C++的下一个奇迹,再次与C++一起涅磐而重生……

本文地址:http://com.8s8s.com/it/it23319.htm