2004年12月12日星期日

《Stan Lippman:“C++/CLI全景体验”开栏致辞》的读后感

在CSDN的《程序员》专栏中看到一篇Stan Lippman关于他的C++/CLI的致辞。其实这篇文章还很新,上个月的文章而已,但是由于发布以来,网上出现了无数的评论,所以,到像是一篇旧作了。我是先看到别人关于C++/CLI的评论,然后才看到Lippman的这篇文章。尽管有不少C++程序员骂Lippman是叛徒,然而Lippman的这篇文章却让我非常的欣喜和鼓舞。另外,Lippman确实是那种大拿,写起东西来,深入浅出,虽然谈论的问题已经是语言前沿的东西,但是并不卖弄词汇概念,故作高深,把事情讲得非常清楚。看看他以前得《C++ Primer》就该明白他的风格。
我有些怀疑,骂Lippman的那些人是否真地看懂了Lippman的这篇文章。如果看不懂,那么只能说是水平太差了,根本没有资格对Lippman说三道四。如果看懂了,亦然这么说,那么应该是过于保守顽固了。

我的几点感想,嘿嘿,其实和Lippman的这篇文章关系并不大。Lippman的这篇文章已经说得非常清楚,我实在是没有资格来评说。
最大的感想,关于动态性。其实,我没有怎么接触过动态性的语言。在C++中,跟语言动态性沾点边的大概是RTTI吧。这是一个为广大OO程序员所不齿的一个东西。我以前也一直这么认为,一直到学习到了一点Java的Reflection的时候,才明白RTTI是个好东西,但是C++中的RTTI不够好。
按照OO的思路,对象和对象之间不需要了解对方究竟是什么样的对象,只要知道对方是什么接口就可以了。而RTTI却是要从接口还原出具体的对象出来,这当然和OO的思想背道而驰。
然而,我们应该明确的是,为什么要OO。我以为,OO的利益来源于OO的principle。例如,以OCP为例,对功能的扩展要Open,对代码的修改要Close。因此,如果只是操作接口的话,那么可以通过修改实现来扩展功能,而不需要对接口的调用。
如果使用RTTI,在运行时,判断对象的具体型别,然后根据不同的型别作不同的处理,这将完全破坏OCP。当对实现进行扩展时,也就必须扩展对不同型别的处理,这就直接破坏了对接口调用的封闭性。
然而,RTTI不只是这么一种用法,另一种用途是,在运行时,决定要生产什么样的对象,甚至在编写代码时,都不曾声明的对象也可以在运行时生成出来,这是拜Reflection和动态语言所赐。
我们回过头来,看OCP。实际上没有绝对的OCP。设计者可以把变化抽象成接口,并用不同的实现来提现变化,还可以用多种设计模式来把这些对不同实现的处理集中在一起,例如factory模式。可是归根结底,总有个地方,需要知道,要知道究竟有多少种不同的对象,究竟要生成什么样的对象,如何生成这些对象。把这些过程全都放在一个factory里面,这就是从语言层面上来说,C++的尽头了。如果还要更进一步,就要用到COM这样的东西了。
RTTI中的Reflection可以通过一个标识符来动态的生成对象,从而解决这个问题。一个貌似完美的OCP解决方案。Java利用Reflection,在这个方面,把C++远远的超越了。
所以RTTI也许不是OO,但是他比纯粹的OO更加符合OCP,从而使我们的程序更加优雅。有什么理由来拒绝如此优雅的设计?
而终于,在C++/CLI那里,我们得到了有Reflection的C++。就为了这个,也值得为C++/CLI欢呼。

另外,看到Lippman提到追踪句柄和STL的时候,我的心头一惊。以前没有想过这个问题,但是就这么一说,也能马上想到,这是一个非常复杂的问题。复杂到什么程度?千头万绪,无从说起。如果让我来解决这个问题,要作的第一件事,就是再去读一次STL的源码,在所有会被托管堆引起麻烦的地方作上记号。我估计这么一来,STL的源码中,可能会被密密麻麻的记号所充满。
看到后来,Lippman说要让追踪句柄和普通指针有互操作性,又说到关于C++/CLI对模板的支持。我才觉得松了口气。如果解决了这两个问题,那么对STL的支持,大概也就迎刃而解了吧。
唉,大师就是大师,看问题是高屋建瓴,从根本上解决问题。回过头来,看我的想法,只能说是一个修补匠的思路。
以后如果有面世人的机会,可以用这个题目来考人。如果回答逐行修改STL源码的,嘿嘿,立马拒掉,哈哈。
不过,提到C++/CLI对模板的支持。我隐约感到,这是一个意义非常重大的东西。模板和动态语言,金风玉露一相逢,这里好像有不可思量的潜力,也许会出现对设计模式革命性的扩展。哦,真的是不敢想像,也无从想像。
我非常期待,C++/CLI……

点击下面的链接,可以阅读Lippman的原文:
http://editblog.csdn.net/programmer/archive/2004/11/25/931.aspx

没有评论: