哲学家说:有什么样的世界观,就有什么样的方法论!

  辩论家说:立场决定观点!

  世界之所以有技术思想和观点之间的争论,完全与瞎子摸象的场景一样。真理只有一个,但是却很博大精深,没有一 个人能看得到她的全部。每个追求真理的人都能感觉到她的存在,因为毕竟可以触摸到她的一部分。于是,人们会发现自己摸到的部分是实实在在的,自然与其他人 不同,争论难免。真理就像一个极限,我们永远只能接近她,而不可能拥有她。软件思想的发展也是一个不断接近真理的过程。

  刚开始有计算机程序的时候都是“面向算法”的,人们为了充分发挥有限的硬件资源而设计出各种经典的算法,“计 算机”就是用来计算的机器。但随着硬件能力的提升与程序的复杂度增加,人们发现复杂的代码难于阅读和维护。于是,程序“结构化”的思想开始发展和成熟。 “把大问题分解成小问题来解决”是人类思维的习惯。冗长的代码被分成若干的子过程,每个过程都便于理解,在此基础上也就理解了整个程序。

  其实,“面向算法”与“结构化程序”都是以代码为中心的世界观,还是站在“计算机”的立场上。而当人们开始提 出“数据结构”思想的时候,才真正开始把思考转向要解决的问题本身!人们越来越清楚地认识到,用数据结构去描述问题领域的模型,才是解决问题的关键,代码 只是为数据服务的。从此,以数据为中心的世界观开始逐渐形成。当然,“数据结构”是伴随“结构化程序”的思想而发展的,这种思想的结合极大提升程序的编写 效率,也提升了软件生产率。

   但这种思想还是将“数据”与“代码”分开来思考的。事实上,在“面向对象”思想成熟之前,有经验的程序员已 经感觉到“数据”与“代码”应该是一体的。他们已经习惯将那些复杂的问题划分为若干相对独立的数据结构,并围绕每个数据结构编写一堆服务于该结构的子过 程,而过程的第一个参数就是一个结构的指针,这个指针就是人们熟称的“句柄”,英文叫HANDLE。其实,这就是最原始的对象模型。当“面向对象”的思想 被提出的时候,我相信他们是最先理解此概念的一群人。

  应该说“面向对象”的思想是第一次站在现实世界的立场上看问题,这种思想把人类思考问题的基本模式(如“分 类”,“抽象”,“普遍性与特殊性”)应用到软件设计中。这种思想反映到编程上,就是将“数据”与“代码”统一成一个“对象”,“对象”成为实现软件的主 要方法。软件思想发展到这时候有一点返璞归真的感觉:原来可以用这样简单的思维方式去考虑复杂的软件问题!

  然而,随着这种思想的深入应用,新的争论又开始,但所有的争论都已经是在另一个高度上。我想,在软件思想上,最迷茫的应该是“继承”与“组合”之争。

  由于人们太习惯“面向对象”的方法了,用基类来实现普遍需要的功能,派生子类来实现特殊性的东西。类的层次结 构就像一棵美丽的圣诞树,真的很直观。甚至,许多编程语言为了构造这棵美丽的圣诞树而牺牲掉多重继承的特性。但问题是,一旦这样的继承结构被固定下来,就 规定了系统的生长模式:只能长出新的枝叶!尽管,用类继承模式设计出来的系统具有良好的扩展性,不过这种扩展是单向的。当要想在根基上扩充点东西的时候, 才发现这可能会动摇整个大树!有的程序员试图用多重继承来解决这一问题,但切不说许多语言不支持多重继承,如果真的能扩充一个基类,那么你将面临层次不同 的分支点,应该把哪些枝丫切开呢?

  为此,一种称为“接口”的软件思想诞生了。“接口”思想提倡尊重对象的隐私,从来不去查一个对象的祖宗三代, 只要你能做事就行。每一件能做的事情都被定义为一个“接口”,一个对象对外的能力就是由它的那些“接口”组成,至于它怎样做无关紧要。“接口”的编程思想 就是站在“功能组合”的立场上看问题,而不是来自父类的“功能继承”。因此,对于“接口”思想来说,不管是基础功能的增加还是的扩展新功能,都是扩充一个 接口而已,不再面对复杂的分支与层次结构。

  “继承”与“组合”仅仅是两种看问题的方式。如果你喜欢竖着看世界,你会发现世界是“继承”的。如果你喜欢横着看,你会发现世界是“组合”的。

  事实上,“面向方面”的思想就是横着看世界。“面向方面”是“面向对象”思想的延续,是对“接口”编程的一种 理论总结。它把现实世界所有问题分解成需要解决的各个基本方面,即所谓的“横向关切点”。这些基本面的问题解决是相对独立的,而其组合起来就能解决全部问 题。当发现个别问题还有需要进一步解决的问题,可以在个别的局部范围解决这个问题。而发现普遍要解决问题的时候,也可以给所有的对象增加另一个基本接口面 而加以解决,但不会影响其他已经解决的各个方面。

  将来会不会有一种能够统一“继承”与“组合”的软件思想呢?我想肯定有!而且新的思想和理论肯定会很容易被人们理解,人们又会发现世界原来如此简单,也本该如此简单!

  在此给大家探讨一个有趣的问题:

  继承的观点认为,所有自然数的祖先是1;然后,2和3是继承1的;但2和3是不同的;4具有2的特性,是从2继承的;5既没有2的特性也没有3的特性,是直接从1继承的;显然6继承了2和3的特性...

  组合的观点认为,任何自然数都含有1的成分,素数2、3、5、7是组成自然数的基本方面,其他的自然数都是由素数组合而成,所以称为合数。

  而大家都知道,任何自然数都可以因式分解为1与若干素数相乘,因此可以把1和素数看作自然数的原子特征。如果 自然数B能被另一个自然数整A除,则表示B一定具有A的全部特征(继承思想),而构成A的质因子集合一定是构成B的质因子集合的子集(组合思想)。这是数 论的最基本常识,从这里看问题,前面两种思想是统一的。

  值得注意的是,两种观点都承认1的重要性,而1就是几乎所有高级的面向对象语言中都存在的那个Object,不管你是否愿意它都存在。这就是Object存在的哲学依据!

  但愿将来一切软件思想都这么容易理解...

  今天是2005年上班的第一天,在开始新一年的程序人生之前,仅以此文献给和我一样的所有程序员。


李战(leadzen).深圳 2005-1-4