对象已死?

  最近常有一种说法,就是我们如今面临着另外一场编程模型的变革,面向对象技术已经处在被淘汰的边缘,函数式语言会取代面向对象技术成为主流方式,甚至出现了面向对象已死的言论。作为一个硬核函数语言的狂热者,我个人当然希望函数式语言可以一统天下,成为主流之选。但是不是应该把对象技术和函数技术对立起来,说式后者取前者而代之,我个人认为,这和如何看待面向对象技术有关。

  做为工程实践的对象技术

  在这个年代,大家有一种神圣化面向对象技术的倾向,很多人都把对象技术奉为高深的思想和理论。但实际上,面向对象技术仅仅一种工程实践而已,它是依托于其他技术而存在的一种实践,本身并不是一种完备的计算模型。

  在计算机科学发展的早期,对于计算机的非数值计算应用的讨论,以及对于可计算性问题的研究和发展,大抵确立了几种的计算模型:递归函数类、图灵机、Lambda演算、Horn子句、Post系统等等。其中递归函数类是可计算性问题的数学解释;Horn子句是prolog这类逻辑语言的理论基础;lambda演算成为了函数式语言的理论基础;图灵机是图灵解决可计算问题的时候所设计的装置,其后成为计算机的装置模型,与图灵机相关的自动机以及冯诺依曼结构,成为了命令式语言的理论基础。

  因此当我们谈及函数语言和命令式语言优劣的时候,我们实际上是在讨论其背后的计算模型——也就是lambda演算和冯结构装置操作——在执行效率和抽象层次上的优劣。

  而面向对象技术则比较尴尬了,其背后没有一个对应的计算模型(80年代的时候曾有人研究过,Pi演算是个备选,但是这个模型更多的是在并发对象领域的语义,而不是通常意义上的计算模型)。它有点类似于“最佳实践”,在不同的计算模型上有着完全不同实现方式和含义。因此对比对象技术和其他技术的时候,搞清楚到底是哪一种面向对象就变得格外重要起来。

  两种不同的面向对象

  目前流行的对象技术,实际上有两个截然不同的源头。它们分别在两个完全不同的计算模型上发展起来,但是都顶着“面向对象”这个帽子。

  第一种对象技术出现的较晚,在1979年以后。它是以抽象数据类型(ADT,Abstract Data Type)为源起,发展出来的面向对象技术。也就是首先被C++所采用的面向对象技术。

  C++作为“更好的C”,继承了C语言对于程序的看法,也就是数据抽象(Data Abstraction)和过程。面向对象技术在C++中,是作为一种更好的数据抽象的方式而存在的。

  数据抽象在这类面向对象语言中是一种关键的抽象方式。所谓数据抽象,在计算机发展的早期是一种非常关键的技术。众所周知,计算机在装置模型上是一个存储和一组指令集,而二进制的存储实际上是没有任何类型表示的。整数,浮点这些操作必须通过相应的约定,再以指令集的形式进行支持。而随着计算机的发展,简单的数据类型显然已经不能满足应用的需要。这时候一种灵活且有效的类型系统,就成了一种自然的追求(直到80年代初,类型系统都是计算机科学研究的重要方向之一)。

  在C++中(以及后来的Java和C#),对象是一种构造数据类型的方式,把每个“类”看作一段存储(状态)和操作(方法)的集合。“类”作为已经存在的类型系统的一种扩展(这一点在C++中体现得尤其强烈)。在这类语言中,“类”(class)实际上代替了“对象”(object)成为了头等公民。构造一个更好的类型系统,是这种面向对象技术所要解决的问题。与其说是面向对象,不如说是面向类或面向类型的。

  从计算语义上说,这类对象技术仍然是装置的操作语义,和面向过程的没有实质上的区别。唯一的不同是,被这种对象语言操作的机器,可以借由对象技术扩展机器所支持的类型。这种面向对象技术是过程技术的一种发展,虽然在抽象层次上没有什么太大的提高,但在实践上已经是巨大的进步。

  另一种对象技术出现的很早,大概在60年代末就出现了,直到80年代初还有发展。但是很长一段时间内并不是太主流的做法,反而并不太为人所知。

  在函数式语言里,因为高阶函数(High Order Function)的存在,数据可由函数来表达。这就是函数语言里一个非常重要的观点:Data as Procedure。在函数语言中,可以构造一种非常类似于对象的高阶函数:

(define (make-user name age sex)
(define (dispatch message)
(cond ((eq? message 'getName) name)
((eq? message 'getAge) age)
((eq? message 'getSex) sex))
(else (error 'messageNotUnderstand))))
dispatch)

(define vincent (make-user 'Vincent
30 'Male))
(vincent 'getName)

it知识库对象已死?,转载需保留来源!

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。