1.2 面向过程与面向对象
前面我们提到了面向过程和面向对象的概念,作为计算机编程理论发展过程中最为重要的两种思想,在正式接触设计细节之前,我们绝对有必要先来弄清楚一下它们的来龙去脉。
计算机之所以出现,就是为了帮助人们解决科学计算中人类无法承担的大量的繁重计算,这也是为什么我们称之为“计算机”的原因,所以初期的程序也基本都是集中在科学计算的相关方面。对于科学计算来说,问题解决起来就简单了,基本就是把数据放到一个统一的地方,然后把计算过程分为几步,每步使用一个函数去操作那些数据,最后用主函数把这些小函数串起来调用一遍就得到结果了。这个过程其实就像小品中说的:“请问,把大象装进冰箱需要几步?”答案是:“分为三步,第一步打开冰箱门,第二步把大象塞进去,第三步把冰箱门关上。”
随着计算机技术的不断提高,计算机逐渐被广泛用于解决各个领域的问题,于是计算机处理的问题越来越复杂,程序的业务流程也越来越庞大,因而实现业务的函数也越来越大,越来越多。于是程序设计开始不得不先使用最主要的外层函数来实现空的流程外壳,然后逐步细化每个外层函数来生成更多的内层的函数,直到最内层的函数完成功能,设计结束,如图1-1所示。
这些最外层的意义丰富的函数就叫做模块,这就是模块化的思想。
模块化和函数 构成了面向过程(Procedure Oriented)编程的主旋律;从上往下,步步细化,以函数为编程的基本单元来组织整个软件的运行流程,这么做简单粗暴,但是相当有效。
这个思路一直高效运作,直到计算机处理问题的复杂程度超出了函数的能力范畴,人们才不得不重新考虑编程的基本单元。
就好比一个国家开始的时候,1毛钱能买很多东西,大部分时候1毛钱就够用了,1块钱的东西算是比较贵的,如果没有1块钱,也只需要掏出10个1毛钱就可以了,所以主要印刷1毛钱就行了。但是随着物价越来越高,很多东西都是以10块为起卖价了,甚至还有一些东西已经卖到100块,这个时候如果还是以1毛钱为支付的主要钱币,那么买100块的东西,乖乖,你要带着1000张1毛钱去买东西,这该多么可怕啊,于是大家不得不改为以印刷10块钱为主。这种新10块钱的主流纸币在编程理论中就是“对象”。
我们回过头来看面向过程的过程,通过前面的分析,我们知道函数的本质就是计算的步骤,代表的是一种行为。这些函数使用的数据集中存放在一个地方,需要的时候去拿就可以了。这个过程是以函数作为最基本的逻辑单元构建出来的整个业务系统,这里处处都透出全局的味道,函数是全局的,数据是全局的。但是随着问题越来越复杂,有些数据很明显需要控制起来,不再是所有函数都能访问的,而且很多函数之间越来越表现出很强的关联性,于是一个更加强大的逻辑单元,第一次将程序的两个基本要素——数据和算法,结合起来的超级元素“对象”诞生了,设计思路迈出了关键的一步,如图1-2所示。

图1-1 程序设计流程

图1-2 面向对象
面向对象(Object Oriented)不是抛弃面向过程,而是在过程的基础上,把数据加入抽象的范畴,理解这一点至关重要。
面向对象仍然是基于模块化基础上的思考方式,只不过描述业务逻辑的功能单元不再是代表单一行为的函数,而是行为和数据的混合体——“对象”。相比面向过程,面向对象最主要的进化就是把问题领域中的事物给对象化了,对象包括属性与行为。在这个抽象的过程中,为了描述私有性,封装来了;为了描述传承性,继承来了;为了描述差异性,多态来了。
人类世界的发展在继续,计算机的发展也在继续,渐渐地,人们发现在对象的使用过程中,总是有些东西是贯穿多个对象的,比如记日志,基本上每个核心调用都可能用到,其他的还有像安全性检查、登录状态检查、性能检查等,相对来说,它们虽然不是核心的业务逻辑,但却是系统不可缺少的步骤,这些离散的特性使得我们并不能用继承的方式去复用这些功能,于是立足于解决这种问题的编程理念——面向方面编程出现了。
面向方面编程将这些重复的但是无法通过简单继承来复用的功能称为方面,将方面抽取出来后创建专门的对象来表示它们,然后在编程中通过各种静态注入(代理),或者动态注入(反射)的方式来融合到原来的对象体系中实现复用。所以,方面是对象的一种补充,而没有从基本概念上做出新的突破。
面向方面(Aspect Oriented)不是替代面向对象的,而是作为对象编程的有益补充而存在。
接下来,随着分布式系统的大范围应用,软件分布的范围也在逐渐扩大,于是模块可能不在一起了,有些模块被单独放置在某个地方,供其他模块,特别是某些远程模块调用;也有可能公司业务重组,有些模块被保留供别的业务使用,总之,这些模块可统称为服务,如图1-3所示。

图1-3 面向服务
面向服务(Service Oriented)也不是替代面向对象的,它是在对象的基础上,提供了更大粒度的抽象。
面向服务研究的重点在于模块的分布式部署和使用,目前基于XML这种中间格式的SOAP协议或者REST开发方式最为热门,它们解决了不同实现的系统(异构系统)之间的分布式开发。所以服务仍然是对象的补充,并没有从基本概念上做出关键突破。
回顾上面这个不断发展、不断创新的过程,我们发现:
(1)科技的进步来源于实际的需求,请时刻记住“实际的需求”,因为这一点是很多理论的基石,比如敏捷开发、简单设计、重构等。
(2)量变带来质变,最重要的就是过程到对象的突破,大数据和云计算是新的量变,这次量变什么时候引发质变呢?大家拭目以待,当然也有可能由你来突破这关键的一点。
(3)设计的思路从来都没变,仍然还是模块化,层层细化或者反过来。
(4)面向对象仍是设计的核心,它包含了其他面向XX的思想。