连载03:软件体系设计新方向:数学抽象、设计模式、系统架构与方案设计(简化版)(袁晓河著)

统一化

打破了这种集合关系,那么我们需要重新整理一下我们的思路,这些特征到底是什么关系呢?感觉有点乱。

不过没有关系,我们先跳出面向对象的原有的思维方式,我们先从计算机的最基本的处理来看,在计算机里面我们使用 (值,地址) 这样的关系对来表征整个软件的框架体系,任何运行的最小单元,都可以具有某个状态的值的信息,同时必须占用空间,没有无值的地址,也没有无空间的值,就像计算机中的0和1,是相辅相成,对立统一的,而值和地址是可以相互进行转换的,值可以通过间接地址进行指引,而地址可以转换为值进行表示。
其实这种(值,地址)的关系,对于我们的东方古人,其实已经见怪不怪了。我们的祖先就已经有:气分阴阳,阴尽成阳,阳尽成阴,事物都是阴阳组合而成的,不存在孤立的阴,也不存在孤立的阳,阴阳相互相成,统一共存。而这也是矛盾的对立统一,所以(值,地址)就是我们的阴阳,而且两者还可以相互转换。只是我们在进行某一个方面的时候,我们着重谈论起“值”的意义,或者在另一方面谈论其“地址”的意义,但是实际两者缺一不可。虽然我无法达到我们祖先那么高深的境界,只是简单粗糙的认识到这种对立统一。但是,对于本书谈论到的阴阳(“值和地址”),其相对于计算机软件设计来说,不仅仅是这两者的关系,同时必要的是这两者之间的转换。 
对于赋值来说,是将一个值置换成另外的一个值,而通过间接访问的指针可以在更改指针中的值信息来指引到另外的地址空间中,而这种指针具有一种地址位置更换的功能。
这就是计算机系统的基本框架,通过数据(值)与空间位置(地址)的相互转换,构成了最为基本的要素,而数据值与空间位置的相互转换可以看成一种统一的变换过程,这种过程我们称为“置换”,其置换操作的结果就是,无论通过哪种方式进行获取而得到的引用结果是确定的、唯一的、并且是等效的。
对于更多层面来说,值与地址的相互转换,还表征于其他不同层面的操作形式:赋值、指针、引用、函数、函数指针、继承、抽象、实现、泛化、实例化等等方式来处理。这些操作是否也一样具有这种“置换”操作呢?
先说说引用,经典的定义引用就是一个别名,而别名正好表达一种可置换逻辑上的语义表征概念,而对于函数来说,是一种操作的简单归类和抽象,函数具有地址,所以可以表示为函数指针,说明可以通过置换方式进行地址位置的置换,同时在调用的地方是一个站位符,需要通过具体的实现来置换这样的一个处理。所以它们在定义和使用过程中也是具有这种相互转换的“置换”的能力。
类的划分。决定了类与类之间的关系,不同的类的划分,呈现了不同的类关系。那么哪一种方式更好呢?只是面向对象必须回答的问题。
类是按照操作集进行划分的吗?或是按照成员变量进行划分的吗?还是按照抽象意义进行划分的呢?
为什么要使用抽象化原则呢?因为复杂的策略并不比简单的规则做得更好,而抽象的思想就是去繁化简的过程,简化其规则将更有利于进行方案的比较,面向对象、泛型编程、结构化等都是不同的抽象方法,抽象才是成为设计的基础。
设计者的经验是划分方式之一,通过与现实或已经有的经验进行划分,这与现实世界的划分是否相符呢?或者说现实世界的本身就是无序的,是无法进行划分的呢?,其相互的关系必须由人的认识的层次决定的吗?我们的对象模型按照不同的类关系(类结构)会导致不同的框架以及方案吗?静态结构和动态结构处理可能是不一样的,对于置换方式来说,为什么此方式比彼方式更具有扩展性呢?


而对于面向对象的软件设计,我们在前面进行了一些澄清,我们需要从另外的角度来考虑我们的抽象和继承以及实现,但要求我们在概念上不要被故意引入集合的包含关系中。

面向对象的思路是从现实的物理世界中,意识的认知观念上来重组计算机基本概念,它们相互之间的关系可以通过下图来简单描述。



通过上面我们可以看出,现实中的对象和我们在计算机世界中的对象不是一回事,其应该是抽取其部分特征或根据认识的需要进行了一些转换后的映射结果。所以:



    现实世界是不包含所谓的类,只存在的各种各样独立的对象实体,而这些对象实体也无法通过逻辑来完整定义的,而这些对象是客观的,不是因为我们如何归类的方法而让其改变其实质,所以现实对象是我们设计中的直接参照物,但是也并不是唯一的参照物,很多时候,计算机中的对象不仅仅描述现实中的对象的描述,也可能是这些对象中某些操作汇集而形成的对象。
在面向对象之外,对于一些例如结构化编程理念中,也是具有对象的概念,而这种概念不是通过所谓的类进行创建的,而是将其外部表现一致的实体都看成一个对象,一个很好的例子就是在windows操作系统中,对于进程、文件、信号量、图形等都会返回一个统一的操作成为句柄,这个句柄就是对象的ID,虽然对于这些不同的实体进行的操作各不形同,但是其传入的句柄是一致的,在外部表现上,其操作的就是一个具有统一整理和编号的对象。所以在图1-2中,我们将现实中的对象通过映射形成计算机中的对象。
在面向对象的理念中,希望通过模拟人在看待现实对象中的一些归类的思想,在逻辑上对这些对象的部分特征进行抽取形成不同的类属,然后建立一套类的相互关系,并通过类以及类与类之间的关系,来简化对物理世界的充分认识,这里大家要注意,使用这种方式其实是一种简化的操作,既然是简化那么就可能存在部分特性的消失(虽然,可能觉得这是一件多么失望的理论,但是,我们应该认识到,简化是一个具有重要意义的认识方法论,如果不采用简化的方法,那么我们永远都无法去认识这个世界,我们还是要正确看到我们有限的一面)。
因此,面向对象的理念只是人类在看待和处理物理世界的一个方式和方法,是物理世界的一种划分,这种划分能够让人类意识形态更加方便和简单,是否一定就是最好最准确的划分,其实并非如此。这种划分形式,其实在很多时候,就像人类利用工具一样,利用面向对象的方式,在处理计算机世界中能够达到降低成本、提高开发和使用的效率等功能性方面而推动面向对象的理论,所以,我们不能简单地、片面地认为面向对象是正确的不二法则,当然同时也要明白,面向对象的这种思想是一种在逻辑层面能够简化我们的设计和开发的一种非常好的手段。
其实这本身就是因为意识形态只能无限接近于物理世界的,因为物理世界是无限大的,通过有限的意识认识,只能无穷逼近无限大,而不能完全达到最后的彼岸。这句充满哲学味道的话,也许你还十分的怀疑。不过对于计算机中的类,那绝对是只抽取了意识形态认识的对象的部分特性,也就是说不管意识形态的对象是否达到物理世界的对象,但计算机中的类表达的肯定是物理世界对象的部分特性的逻辑简化认识。
另外在上面我们也提到,人类在认识的过程中,有时候为了统一划归,将一些现实对象的操作集合或者现实对象的状态都划归为一个类,这个类其实在现实世界中是很难找到对应的实体,但是这样的划归却给我们的设计和实施带来了更加强大的便利,我们可以通过这样的统一划归让我们的设计的不同部件之间耦合程度大大降低,这样的手法在设计过程在后面的描述过程中也是处处可见。
在面向对象理论的不断深入过程中,人们猛然发现,如果将这些操作集合再进行分类,于是就形成了一个高度抽象的实体,这个实体就称为接口,而接口的概念更是体现这种逻辑上的划分,在现实世界其实是没有这个实体的,所以我们只有这样规定,不能创建接口对应的对象,通过这样的解释,大家是否应该明白了这个道理了吧(逻辑与物理并非是一对一对应的,所以优秀的软件设计师往往创造性的给出一些逻辑上新的概念,让设计一下子简单明了,这就叫妙笔生花)。这个接口的概念,对我们的设计带了深远的影响,它同样让不同部件之间大大解除了耦合。
在计算机中的对象是具有空间分布和运动时间的逻辑实体,也就是说是(值+位置)的组合的一种方式。计算机中的对象的规则是通过计算机中的类来限制的,或者说计算机中的对象是通过计算机的类进行实例的结果,而计算机中的类是计算机中对象进行抽象而来的(这里大家可能要注意,我并没有按照传统的方式认为计算机中的类是通过现实的对象进行抽象的说法,而是说成是归类,这样会更加准确一些),因为计算机中的类的确和计算机中的对象是相互对应的,一个是物理上的计算机的对象,一个是逻辑上的计算机的类。虽然有时候我们也可以将计算机的类通过一些其他的方式来描述,例如JAVA、VCL、MFC等的动态类,C++中的typeof的相关操作,但是面向对象的类的概念依然是逻辑上的,只是可能通过静态方式描述,也可能通过动态方式进行描述的区别。
在新的百科上又是这样的描述:
类是对某个对象的定义。它包含有关对象动作方式的信息,包括它的名称、方法、属性和事件。实际上它本身并不是对象,因为它不存在于内存中。当引用类的代码运行时,类的一个新的实例,即对象,就在内存中创建了。虽然只有一个类,但能从这个类在内存中创建多个相同类型的对象。
这是从类是否能够实例化为在空间和时间上具有的对象(实体)所表达的方式,类其实是可以描述的,而且在内存中也是可以描述的,只要我们通过“映射”方式能够将具体的对象通过类进行映射,则类就可以存在于内存中。比如java语言中的反射机制也可以看到,类也是可以描述出来的,只是不能脱离“映射”方式来孤立描述,类是在“关系”中存在的。
从上面可以看出,由于面向对象的思想更体现了逻辑意义上的变换(所以面向对象会招致很多的质疑,其实这种质疑是一件好事,这样可以检验我们设计过程中,这些通过间接方式的逻辑变换,是不是违背了物理世界的基本规则,是不是影响我们的设计结果)。
通过上面相关的描述,苟且希望我能够比较清楚地理清了这些概念的关系,能够为下面的分析打下一个好的基础。

本文链接:https://my.lmcjl.com/post/5596.html

展开阅读全文

4 评论

留下您的评论.