提起面向对象的语言,Alan Kay和他的Smalltalk在历史上必须占据一席之地。许多Smalltalk的面向对象的特征,现在Java和C#都不具备。当然不能说历史在开倒车,但确实很多闪光点被淹没在冗长、沉闷的历史中了。

Smalltalk 和面向对象编程

Smalltalk是最有影响力的编程方式和语言之一,几乎所有后来出现的面向对象语言——Objective-C、Java、Python、Ruby和许多其他语言——都受到了Smalltalk的影响。此外,Smalltalk也是敏捷软件开发方法,快速应用程序开发(RAD)或原型设计以及软件设计模式的最流行的语言之一。

面向对象分析的全过程(面向对象刨根问底4)(1)

Smalltalk环境通常是第一个开发现在常见的面向对象软件设计模式的环境。其中最流行的是用于用户界面设计的模型-视图-控制器(MVC) 模式。MVC 模式使开发人员能够拥有相同基础数据的多个一致视图。它是软件开发环境的理想选择,其中存在相同底层规范的各种视图(例如,实体关系,数据流,对象模型等)。此外,还可以从不同角度和抽象级别查看基础模型的模拟或游戏。

除了MVC模式之外,Smalltalk语言和环境在图形用户界面(GUI)的历史中也具有很高的影响力,你所看到的就是你所得到的(WYSIWYG)用户界面,字体编辑器和UI设计的桌面隐喻。Smalltak的创始人Alan Kay说:

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in Lisp.

Alan对面向对象的理解,是多个生物体(计算机)互相通过消息发生作用,提高编程效率。面向对象对他来说是消息、内部状态过程的保持、保护和隐藏以及延迟绑定。每个生物体会有内部隐藏的状态,状态不可以被直接修改,而应该通过消息传递的方式来间接地修改。

面向对象分析的全过程(面向对象刨根问底4)(2)

到这里我们可以看出面向对象编程的两个最基本的特性:封装和消息传递,那么延迟绑定是什么意思?延迟绑定指的是对象内部的实现可以在运行时进行修改,而且不会破坏整个系统的其他部分。这个特性其实是和封装直接相关的,在面向对象编程中被封装的对象之间是相互隔离的,在极端情况下,是一个电脑中的所有对象都可以通过远程调度被另一电脑完全接管。

与大多数其他语言不同,Smalltalk 对象可以在系统运行时进行修改。实时编码和“实时”的应用修复是Smalltalk的主要编程方法,也是其效率的主要原因之一。反射是计算机科学家应用于能够检查其自身结构的软件程序的术语,例如其解析树或输入和输出参数的数据类型。反射是动态的交互式语言(如 Smalltalk 和 Lisp)的一个特性。具有反射(解释或编译)的交互式程序维护所有内存中对象的状态,包括代码对象本身,这些对象是在分析/编译期间生成的,并且可以通过编程方式访问和修改。

此外,由于封装所带来的面向对象方法具有组合递归性。这种相似的构造方法可以使得软件能够构建出庞大规模的虚拟世界。

Smalltalk 的MVC模式

在Smalltalk-80中,类的模型/视图/控制器(Model/View/Controller)三元组(MVC)被用来构建用户界面。透过MVC来看设计模式将帮助我们理解"模式"这一术语的含义。

MVC包括三类对象。模型Model是应用对象,视图View是它在屏幕上的表示,控制器Controller定义用户界面对用户输入的响应方式。不使用MVC,用户界面设计往往将这些对象混在一起,而MVC则将它们分离以提高灵活性和复用性。MVC通过建立一个"订购/通知"协议来分离视图和模型。视图必须保证它的显示正确地反映了模型的状态。一旦模型的数据发生变化,模型将通知有关的视图,每个视图相应地得到刷新自己的机会。这种方法可以让你为一个模型提供不同的多个视图表现形式,也能够为一个模型创建新的视图而无须重写模型。下图显示了一个模型和三个视图(为了简单起见我们省略了控制器)。模型包含一些数据值,视图通过电子表格、柱状图、饼图这些不同的方式来显示这些数据。当模型的数据发生变化时,模型就通知它的视图,而视图将与模型通信以访问这些数据值。

面向对象分析的全过程(面向对象刨根问底4)(3)

表面上看,这个例子反映了将视图和模型分离的设计,然而这个设计还可用于解决更一般的问题:将对象分离,使得一个对象的改变能够影响另一些对象,而这个对象并不需要知道那些被影响的对象的细节。在四人bang的设计模式中,这个方法被描述成Observer模式。

MVC的另一个特征是视图可以嵌套。例如,按钮控制面板可以用一个嵌套了按钮的复杂视图来实现。对象查看器的用户界面可由嵌套的视图构成,这些视图又可复用于调试器。MVC用View类的子类——CompositeView类来支持嵌套视图。

CompositeView类的对象行为上类似于View类对象,一个组合视图可用于任何视图可用的地方,但是它包含并管理嵌套视图。上例反映了可以将组合视图与其构件平等对待的设计,同样地,该设计也适用于更一般的问题∶将一些对象划为一组,并将该组对象当作一个对象来使用。

面向对象分析的全过程(面向对象刨根问底4)(4)

MVC允许你在不改变视图外观的情况下改变视图对用户输入的响应方式。例如,你可能希望改变视图对键盘的响应方式,或希望使用弹出菜单而不是原来的命令键的方式。MVC将响应机制封装在Controller对象中,View使用Controller子类的实例来实现一个特定的响应策略。要实现不同的响应策略只要用不同种类的Controller实例替换即可。甚至可以在运行时刻通过改变View的Controller来改变View对用户输入的响应方式。

实际上,类似面向对象的方法可以追溯到 Ivan Sutherland 开发的 Sketchpad 时就已经在使用了,在 Sketchpad 中每一个图形都是由一个对象来表示,这个对象里包含这个图形的所有数据和操作方法。确如一些程序员所说,UI是面向对象的最好的战场,在业务系统中面向对象尤其是继承关系并没有得到很好的应用。我们调查了一些行业,你知道应用面向对象最深入的是什么行业吗?你可能猜到了,是游戏行业,没有面向对象,没有继承,大规模游戏寸步难行。

面向对象分析的全过程(面向对象刨根问底4)(5)

以Delphi为代表的第四代可视化编程语言

下面是C/S版本到达鼎盛时期的编程方式,其中UI元素按钮是一个类,具有属性和方法:设计者通过可视化拖拽和嵌入事件代码能够非常高效率完成需求。从当前Java主流开发技术路线来说,前后端分离、大量中间件生态、数据库连接等等降低了开发效率,也难以贴合这种可视化面向对象的思想。

面向对象分析的全过程(面向对象刨根问底4)(6)

在这些面向对象的工具中,发人员不使用编码,而是采用可视化的操作形成各种所需表单,例如著名的PowerBuilder。实际上,在后来的微软的Visual Basic 和 Borland 的Delphi上,大家已经体会到了什么是低代码开发的高效率。现在的低代码只是那些工具的浏览器升级版本。

遗憾的是,Smalltalk最终没有能够战胜分工协作的工业大潮流,但其精神被苹果公司继承了,苹果至今坚持软硬一体的产业思路。

Smalltalk后继有人--儿童编程Scratch

Scratch是一种高级的基于块的可视化编程语言和网站,主要针对 8-16 岁的儿童,作为编程的教育工具。

面向对象分析的全过程(面向对象刨根问底4)(7)

其实Scratch是一种唱片播放方式,去过D厅的人都知道。中国人看这个名称显然不靠谱。更不靠谱的是这个研发团队的名字,麻省理工的Lifelong Kindergarten group (LLK),翻译过来是终生幼儿园团队

面向对象分析的全过程(面向对象刨根问底4)(8)

国际上的少儿编程课程基本上都是用的Scratch,由于是开源的,国内很多教育培训公司换了个名称,教授小朋友编程课。该语言官方网站上的社区统计数据显示,超过 8200万用户共享了超过 9200 万个项目,每月网站访问量超过 9800 万次。是最受欢迎的、也是小朋友唯一容易上手,感兴趣的编程语言。scratch 3.0 加入了 摄像头互动,乐高机器人控制,以及语音互动功能。

Smalltalk在面向对象编程和JIT及时编译等方面给行业带来了深远的影响。Squeak是一个现代的,开源的,功能齐全的Smalltalk程序设计语言和执行环境,通过语言本身能对所以任何事物进行修改。Scratch是一种基于Squeak、并由Squeak实现的可视化程序设计语言。

Scratch在封装、继承、多态、实例化等方面都很好地体现了"面向对象"编程思想。感兴趣的同学可以试一试,就知道什么是原汁原味面向对象的编程思想了。

结论
  1. 面向对象对生物学的借鉴使其具有大规模复杂系统构建的可能性。
  2. Smalltalk继承、消息传递、封装和延迟绑定等机制,值得现代程序员借鉴,需要关注的是传递过来的Message而不是动作。
  3. Smalltalk由于UI元素的设计促使其应用,交互式组件面向对象应用最能大展拳脚的地方。
  4. Smalltalk并不是一个面向业务分析的语言系统,如果你想做一个企业软件,AlanKay能够给你的经验大多数是哲学思想方面的。

Smalltalk面向对象并没有带来今天所奉行的面向对象的Solid原则,当时都忙着底层事情,上层应用尚未开展。面向对象的理论是如何发展成现在的样子呢?我们下期再见!

博士聊IT,感兴趣加关注,后面更精彩!

软件架构师必读:面向对象编程思想(OOP)的由来与本质

面向对象刨根问底1:新年伊始追忆那些被历史湮没的璀璨星光

软件架构师必读2:一文带你理解面向对象(OOP)中类的本质

,