敲响OO时代的丧钟!——类型系统

阅读更多

  多谢Trustno1的帮忙,他因为忍不住了,所以打算帮我把题破了

写文章,不破不立。我说这句话还不针对你即将要发表的解决方案,只是针对你前5页的"破",本来以为你能说清楚的,但是你破了5页都破不了,看着肚子都痒,索性就用EL这样前人的观点帮你破了,你就快点立论吧。

  而他引用的两段话,一段正好可以用来承上“Elminster的那段关于面向对象与本体论的论述”,另外一段正好可以用来启下“事实上,我们猜想是,如果没有知识表示和自动推力工作的帮助,这些问题(指类,继承)是无法仅仅通过计算机语言设计的方式来处理的。”——SICP 2.5,中文版136页,角注118。

  Elminster那篇论述,正好和我的文章形成一个互补关系,他以极为清晰的表达语言,说明了OO打算以类型化方式描述真实世界,所面临的难题。这也使我不必再次动脑子思考如何回答JavaCup的哲学方面的疑问了。而下面这一段话我想特别再次引用一下:

就我个人来说,比较倾向于认为这条最终是走不通的死路,人是从事物的特征与属性归纳出它的“类型”,而不是相反。某种意义上说,“类型”是为了节省描述时间而产生的 …… 唔,这个太远了,所以就此打住。

  大家记住这段话中的,特征、属性、类型这几个关键字。我先绕个小弯再回到这个话题上来。

  我之前分析的面向对象的哲学漏洞时,也有不少朋友认为,说:“面向对象不能很好的描述真实世界,并非一个有意义的指控。OOA、OOD本来就是用来对需求建模的。也就是打算描述需求世界。”

  其实我的指控分为两个阶段,一方面,OO所依据的哲学导致了软件开发的苦难,而且至今余毒未清。另一方面,即使是指打算对需求建模,OO的技术手段也是有缺陷的。

  就这么说吧:OO的类型系统,原本是从ADT来的。一个抽象数据类型,将数据与操作封装在一起,是出于对于数据被“莫名其妙的修改”的担心。但是,结果呢,一个ADT如果不支持继承,那么它的代码就无法被重用。所以OO就在ADT的基础上增加的一个继承,通过继承的方式来复用以有的代码。这样的思路原本没有太大的问题,如果它仅仅只想表达各种自定义数据类型的话。

  但是在OO的哲学提出之后,一切皆是对象,所以一切出于类型体系之内,对于数据类型的定义,扩展到了对于现实世界中各种实体的类型定义,整个一个类型系统,其内在的语义大大扩展复杂化了。更糟糕的是——引用Elminster的话是从事物的特征与属性归纳出它的“类型”——而因为OO封装也就是隐藏了内部数据,事物的特征与属性,从其本质属性,被转义为对外的提供的操作接口。但是,要分析一个实体的本质,而不是实体的外部表现,更不仅仅是“我能对他做什么”。这才是实体分析有可能成功的关键,而在OO的语言设定中,这却是难以做到的。

  我们来看两张图片

  这是在SICP里讨论类型系统的第一张图片,我称之为“OO成功案例”。

  这是在SICP里讨论类型系统的第二张图片,我称之为“OO失败案例”。

  为什么一个能够成功,而另一个却会失败?以往的解释其实比较“直觉”。看着这个图,就想当然的以为:“这是因为多重继承导致的!”事实上呢?

  第一张图中所显示的成功,很多人会认为这是由于这一个对象塔中的每一个对象都能够支持加减乘除运算。而在几何图形中,这样一致的操作接口不存在了。而事实上,正是因为复数、实数、有理数、整数,在本质属性上有一致之处,他们才能表现出一致的“可加减乘除性”。而不是相反。当我们画出第二张对象关系图的时候,也不是根据几何图形可以接受的操作类型来进行分类与显示继承关系的,而是根据不同的几何图形的本质属性的相近程度来划分类型体系的。多边形的本质是:“多条有限长直线组成了一个封闭图形”,而三角形与四边形的本质则是,边的数量分别为三和四。等腰三角形的本质是,不但边的数量为三,而且其中有两条边的长度相等,直角三角形的本质是不但边的数量为三,而且其中有一个直角。如此等等......

  各位,请再次思考这样的分类体系的内涵。

 

 

  我的结论是:“一个类型,是由其本质决定了所能表现出的可操作性,而不是有其所能接受的操作决定了其本质。然而,OO正好把这个问题搞反了!”

(未完待续)

你可能感兴趣的:(OO,工作)