几个月之前,Slashdot 转载了Robert Harper教授的一篇博客,说卡内基梅隆大学计算机系把”面向对
象编程“从大一新生的必修课中删掉了,其原因是
Object-oriented programming … is both anti-modular and anti-parallel by its very
nature.
这两个原因(anti-modular和anti-parallel)都是很重的指责了;尤其是anti-modular,因为OO的基
本思想通常被理解成“封装”,从而实现模块化。
我是在1995年第一次听说“面向对象”(Object Oriented)这个说法。当时在学习正在成长过程中的
C++,用的是Borland C++ 1.0。从那时开始的很多年里,”类“(class)、“对象”(object)和
“方法”(methods),以及在这些概念之上构建的”继承“(inheritance)和”多态
“(polymorphism)都是我理解中OO最核心的思想。我猜大多数程序员在这方面的认识都和我差不
多。
但是“封装”真的是OO的本质嘛?直到最近为了给iPhone写个玩具程序而学习Objective-C(一种非
常古老和原始的面向对象编程语言)的时候,才注意到早在1998年,OO之父Alan Kay就曾经在一篇
邮件中说,他很后悔发明了“object”这个词,从而误导大家,把注意力都集中到“封装”,而忽视了
OO的本质——messaging(消息传递)。Alan Kay的原话是:
The big idea is “messaging” … . The key in making great and growable systems is
much more to design how its modules communicate rather than what their internal
properties and behaviors should be.
Objective-C的设计是非常强调“消息传递”(messaging)的——对一个object的method的调用,
被称为“给这个object发了一个消息”。为了突出调用method时指定的参数(parameters)实际上
是消息中的一些内容,Objective-C不惜把method的定义方式都做了相对于C的很大的修改,从而把
参数嵌入在method的名字里。比如在一个叫做myWebView对象中搜索一段文字,要求不区分大小写,
从前往后搜索,用Objective-C来描述是:
很明显,c代码要比java简洁得多。本来一个函数可以解决的问题,OO却告诉我们需要一个类,于是就多出了许多代码。我认为编程时一条重要的原则就即:no more, no less. 上述java代码很难使我们认为它是美的。
其次,面向对象方法在一些时候(其实说是很多时候也不为过)并不符合数学的思维方式,而至少当前我们使用的计算机还是基于数学的理论基础创造的。同样还是上述例子,当我们在数学中解决交换数值问题是该是如何思维的?当然是把要交换的内容作为参数传 入函数。正如Joe Armstrong所说,数学的思维方式中数据和函数时分开的。数学家们不会也不许要将这两者粘合在一起构成一个对象或是其他什么东西。当然,按照Martin Vilcans反驳Joe的文章《No, that’s not why oo sucks》中指出Joe并没有提出合理的解释来证明为何数据和函数应当分开。那么请思考以下情况:假设我们现在有两个类: Class A 和 Class B, 我们需要在A的实例中操作B实例中的某个数据,按照面向对象的设计,我们可以有这两种方式: