Ralph Johnson、Joe Armstrong:OOP现状一席谈

个人简介 Ralph Johnson是《设计模式》一书作者四人组中的一员,并且创建了最早的重构浏览器,他现在就职于UIUC公司的CS部门,担任UIUC模式/软件架构小组的主管。Joe Armstrong是Erlang语言的主要发明者。他一直在Ericsson工作,在此他开发了Erlang,并担任Erlang/OTP系统的首席架构师。

QCon是由C4Media媒体集团InfoQ网站主办的全球顶级技术盛会,每年在伦敦、旧金山、东京、北京召开。2009年4月,QCon首次登陆北京。QCon Beijing 2010大会吸引了700多名架构师、项目经理、资深开发者和技术领导者、以及200多家企业的参与,并获得了业界空前的好评!

   

1. 如果我们回顾历史,会发现面向对象起源于Smalltalk-80,它采用的是消息传递(message passing),然后我们再来看一下当前的状况,现在面向对象是基于继承之类的概念,我们的发展方向发生偏离了吗?我们是否应该回归根本?

Ralph Johnson:我们经常会遇到这种情况,当你想到一个主意,然后把它分享出来,而这个主意对于大多数人来说会过于前卫。大多数人都不会完全采纳这个主意,他们可能会采纳其中的一部分,然后你就会得到这种近似的情况。我还记得,当时人们拒绝使用Smalltalk,因为在其中存在垃圾回收机制,而且它还拥有自己的虚拟机字节码和虚拟机,即便我们想要使用一些无效的功能,也需要编译所有的程序。但这种抱怨现在已经不见了。

如果你从事的是底层开发或者实时的嵌入式编程,那么没有人会说在特定的情况垃圾回收机制会对你形成阻碍,因为基本上人们都能够看到它的价值所在。然后让我们考虑一下Java的情况,我认为静态的类型系统(type system)会对我形成阻碍,人们在其中放置了很多模板,使得类型系统更加强大。这样它会变得越来越复杂。总是会发生这种情况,你选择一种语言之后,只要它的限制稍微多一点,你就需要放松限制,你会采用特定的方法来与它们的策略保持一致。

当然,C++也存在同样的问题,它与C语言保持兼容非常重要,然而,它更多的是与C语言的思考方式兼容,而不是与特定的C语言编译器兼容。从那种意义上说,它很成功,因为它保证了与C语言思考方式的兼容性。但是,从一位非C++程序员的角度来看,那就会显得非常复杂。他们创建出这种极度复杂的语言,而使用它的人们却很高兴。

作为旁观者,我觉得对其抱怨是毫无意义的,因为那不是我的语言,但是我发现Ruby和Smalltalk的情况也非常类似。

   

2. Smalltalk的正确和错误体现在哪些方面?

Ralph Johnson:我要再次说明的是,我认为Smalltalk是非常完美的,多年之前,我觉得Smalltalk可能犯了一个本质性的错误。我认为除了Smalltalk程序员之外,其他人都很难喜欢这种语言。因为如果你使用Smalltalk编程,那么在其中进行调试的时候,你调试的就是整个系统。

调试器是在其内部运行的应用程序,其中有编译器,有集合类等等,其中什么都有。当你调试程序的时候,你所做的就是编辑对象。我们没有标准的方式来把Smalltalk代码打印到纸上。Smalltalk代码就是对象。这和编辑Postscript代码的人类似。那种做法对我们来说很是奇怪,但事实上那正是Smalltalk程序员所做的,而且在Smalltalk中是非常易于理解的。

我们已经拥有所有用来展现它的工具,并且能够创建很漂亮的界面。Smalltalk程序员经常会抱怨“这些人总是认为你想要把代码存放在文件系统中,作为文本文件来存储。这简直就是二十世纪的老古董。事实上,那是我们针对二十世纪七十年代所说的,因为在八十年代我们就有更好的方式来处理它了。但是现在有些退步,它告诉人们,什么时候想要增加一些功能,只需要让镜像(image)变得更大就可以。因此镜像变得越来越大了。

我发现,在Smalltalk从Xerox机器中脱离出来的同时,它就拥有了另外一套操作系统,当你进行调试的时候,会发现那更像是一种pascal风格的操作系统。当你在这个操作系统中调试的时候,你会说“调试”,它就会将所有内存中的数据存储到磁盘上,然后重启操作系统,打开调试器,这样你就可以单步跟踪代码,你使用的调试器会在磁盘镜像上完成所有的工作。

有了那个镜像,如果你决定要对调试器进行调试,那么就会再次点击按钮,那样它就会从磁盘上把调试器调出来,系统会弹出另一个镜像,现在你是在最初程序的调试器上运行你的调试器,那正是很多时候你所想要的。显然每次你这么做的时候性能都会下降,但是这样你就更易于跟踪彼此之间的差别,如果我拥有新的调试器,那么我肯定需要使用旧调试器来对其进行调试,那样在我的应用程序中,就易于跟踪所有这一切。

因为在Smalltalk中,所有一切都存在于镜像中。你无法跟踪最旧和最新版本之间的版本,这是个瓶颈问题,而现在我们会使用分布式计算或并行计算。人们会说“我们想要在Smalltalk中拥有多线程。”不,你最好不要那么做!因为那会让你把古老的问题都引发出来。如果你想得到容错性,那么所需要做的就是拥有多个镜像,然后在之间来回传递消息。

这从多年前就开始了,因为我们使用这种方式来做事,我们只是把所有一切都放到镜像中,但这样还是存在复杂性的问题。只要你构建系统,就会存在限制,只有少数人能做好,而在那种情况下Smalltalk无法有效工作。如果有二十个人参与系统的构建工作,那么Smalltalk就不是一种好选择。如果只有有四到五个人参与构建系统,那就没问题。他们可以坐在一间屋子里,这样用Smalltalk就很好,你可以组织四到五个人来开始工作。有些工作可能需要50个人使用Java构建,但是让200人同时使用Java工作会怎样呢?

你最多只能组织四到五个人的团队进行Smalltalk开发。这是因为它本来就是针对小型系统而设计的,小就需要优秀的程序员,他们的编码速度都非常快。但这仍然会存在限制,如果我们有多个镜像,并且使用消息传递,那么就无法更好地处理容错性问题,Joe是这方面的专家,但我认为这会导致团队的膨胀,而这个问题会对解决工具的问题有所帮助。

我可以检查Smalltalk,然后认为“有些事情不太对劲儿”,但是基本上,我喜欢它的动态特性、能够很方便地做出改变的能力以及非常强大的反射特性,你可以做所有的事情。基本上,当我查看其它语言,觉得“它们正在慢慢赶上”。我们会发现,Ruby中有很多内容,但是由于某种原因,Ruby开发者并不认为工具很重要,这让我感到很奇怪。不管怎样,其中还是有很多好东西,人们逐渐赶上来了,那就是我的感觉。

   

3. Erlang语言是面向对象的吗?

Joe Armstrong:Smalltalk让许多事情都走上了正轨。如果你想知道我对于面向对象编程的看法,那么我想说正是由于Smalltalk我的观点才有了改变。我几年前曾经写过一篇文章,应该是一篇博文——为什么面向对象编程很傻。我主要是想要引起人们的主意。他们对此进行了非常有趣的评论,我的确惹恼了很多人,那实际上是我的部分目的所在。我开始考虑面向对象编程到底是什么,并且认为Erlang不是面向对象的,而只是一种函数式编程语言。

但是,我的导师告诉我“你错了,Erlang是完全面向对象的”。他说面向对象语言不是面向对象的。尽管我不确定是否应该相信他的观点,但是我也在某种程度上认为Erlang可能是唯一的面向对象语言,因为面向对象编程的三原则是:基于消息传递;对象之间保持分离;拥有多态。

Alan Kay曾经写过一篇很有名的文章,在其中他提到“面向对象编程这个概念完全被曲解了。它不是关于对象和类,而是关于消息的”。他还说,对于面向对象编程的最初反应过分强调了类和方法,而忽略了消息,如果我们对消息进行更多的讨论,那么它会变得更好。最初的Smalltalk总是会与对象对话,你会向对象发送消息,然后它会做出响应,发送返回的消息。

但你不会真正那么做,你没有让对象真正保持分离,那也是问题之一。Dan Ingalls昨天说到了消息(我认为那非常棒),一旦你获得了消息,就不需要关心消息是从哪里来的。你真的不需要去关心,运行时系统(runtime system)需要对消息的传递加以组织,我们不需要关心它是如何处理的。这在某种程度上会以这种成熟的方式降低发送方和接收方之间的耦合。这也是我喜欢消息传递的原因。

面向对象编程的三原则之一就是要拥有消息传递,那可能也是最重要的。然后是分离,我曾经在之前讨论过它,我的程序不应该破坏你的程序。对于Java可不是那样。如果你将两个程序同时放在JVM中运行,其中一个导致虚拟机停机,那么另一个也会停掉的。你会破坏别人的应用程序,因此它们应该分离。

你需要实现的第三个原则是多态。多态与消息传递的关系尤其密切,它会为程序员提供便利。对于所有对象,或者过程,或者随便你管它叫什么,最好都能拥有printMe方法——“把你自身打印出来”,然后它会把自身的内容打印出来。这是为什么即便它们的名字都不同,程序员也不会记住那一点,因为有多态的存在。它意味着“好的,所有对象都拥有printMe方法。所有对象都拥有度量(size)方法和自省(introspection)方法。”

Erlang拥有所有这些特性。它具备分离特性和多态特性,还拥有纯粹的消息传递。依此看来,我们可以说它是唯一面向对象的语言,可能当时我对面向对象语言所下的结论为时过早。你可以尝试一下,看看它是否具备这些特性。

Ralph Johnson:我认为Erlang拥有两种语言的特性,你至少可以在两个级别上使用这种语言进行编程。一是作为函数式语言,你可以用它编写单独的过程,然后你会考虑所有这些过程是怎么样的,以及它们会如何交互,一个过程会向另一个发送消息。在更高的级别上,Erlang是面向对象的,而在较低的级别上,它是纯粹的函数式语言,这也是长期以来我们广为宣传的。

在较高的级别上,当你从架构设计的角度来检视它的时候,它完全具备面向对象的特性。我认为你在重新定义分离。它会运行在一台计算机上,如果其中的一个过程失控,它就会占用处理器资源。我认为他们会觉得垃圾回收很重要,从而你不需要确保与如何释放资源保持一致。在Smalltalk中与对象交互的唯一方式就是向其发送消息,但问题是你拥有什么样的消息。Erlang中也同样存在同样的问题。

如果你允许大量消息的存在,它会返回你所有局部变量的值,然后每个人都会向你发送消息,你就会设置本地消息的值,如果你这么做了,那么就意味着放弃了分离的价值。那也是为什么你需要合适地进行设计。语言只是会提供一些机制。

Joe Armstrong:当我们拥有上百万个内核的计算机时这会很有用。

   

4. OOP在过去多年间以及在将来会扮演什么样的角色呢?

alph Johnson:当你拥有多个处理器的时候,就会很需要它。看一下新的主意是如何产生的,Jim Coplien今天谈到,面向对象编程并非是一次真正意义上的思考模式的转化,因为你在Pascal中也可以做到。我不知道为什么他会那么说,因为他周围的人们认为这次思想模式的转化来源于人们如何思考,并且是以一种崭新的思考方式。这已经持续了很长时间。

我记得当时我是非常早的OOPSLA,那是在1986年人们所讨论的一个问题,“会有第十个OOPSLA吗?”,我认为会的,因为其中的两件已经发生了。首先,面向对象编程和我想象的一样棒,10年之后整个世界都会那么做。举办面向对象编程会议和举办结构化编程会议一样傻。我们已经这么做了,为什么还需要举办会议呢?

当然,另一个是它没那么好,我们都是受到了蛊惑,我们应该离开。当然,两件事都没有发生,去年已经确实召开了一次大型会议,就叫做OOPSLA,明年会用另外的名字。这一切经历了25年,开展这件事儿非常困难。传播这些观点花费了大量的时间。我们都愿意认为自己能够很快地学习知识,其他所有人也都会这么快速学习,新的观点也会像那样很快地传遍整个世界。但那并不现实。

即便是很好的观点,也会花费很长的时间才能传播开来。

Joe Armstrong:他们只是在自己的小社区内传播,而没有向外传播。Smalltalk就是一个例子,它很好,并且在20到30年之前都有了。

   

5. 我们都很喜欢Smalltalk,我想用这句话结束这次采访。感谢Ralph Johnson和Joe Armstrong。

谢谢。

你可能感兴趣的:(Ralph Johnson、Joe Armstrong:OOP现状一席谈)