不时有人问我,我对OOP的父亲,第一个面向对象的语言Smalltalk的设计师Alan Kay在1998年说过有关OOP的看法。 他从字面上说,“对象”一词具有误导性,而更合适的术语是“消息传递”。 这就是我的想法。
我相信对象之间存在两种正交的交互方式:消息传递和组合。 假设我们有一个要点和一个画布:
Point p = new Point(x, y);
Canvas canvas = new Canvas();
这是消息的外观:
p.printTo(canvas);
消息传递的问题在于,它使对象处于相同的抽象级别。 它们以平等且独立的“模块” 进行通信 ,相互发送数据消息 。 即使它们看起来是面向对象的,整个通信模式还是非常程序化的。 我们试图在一个对象中尽可能多地进行封装,但是仍然不可避免地必须公开其大量数据,以便能够将其与其他对象“连接”起来。
我们将对象变成“小型计算机”,就像一些书中提到的那样。 他们希望有数据,处理数据并返回一些新数据。 这种方法并不能真正解决可维护性问题,我们仍然必须处理大量数据,并要记住对象外部的语义。 换句话说,没有真正的封装。
另一方面,这是合成的外观:
Point p2 = new PrintedOn(p, canvas);
每当我们需要对象进行通信时,我们都会创建一个更大的对象,该对象封装了更多原始对象,并使它们在内部进行交互。 当然,数据也会从一个对象到另一个对象,但这将发生在更大的对象内部。 正如我之前所建议的 ,我们甚至可以使封装器和被封装的“朋友”,使交互更加透明,并避免通过吸气剂甚至打印机暴露数据。
让我再次引用艾伦·凯:
制作出色且可扩展的系统的关键在于设计模块的通信方式,而不是设计其内部属性和行为。
在我看来,他的意思是不是对象的模块 。 这些是不同的东西。 模块是架构的元素,而对象是设计的元素。 这是两个不同的级别。 在体系结构级别上,我们显然需要消息,并且Kay的声明完全正确。 但是,在设计级别上,我们需要可组合的结构来提高可维护性,而消息传递并不能帮助我们实现此目标。
因此,我相信Alan Kay在发明对象,称其为对象并赋予其编程风格“面向对象”的称呼时是正确的。
翻译自: https://www.javacodegeeks.com/2017/12/alan-kay-wrong-wrong.html