置换的公理化过程
前面所涉及到的地址和值的“置换”关系以外,赋值、抽象、实现、继承等也都是一种“置换”的关系,而这种“置换”关系是否只是逻辑上我们的一个创造呢?还是客观现实中存在呢?这里我暂时先给出结论:“置换”变换其本质上是物理上存在的一种变换操作,只是我们将之应用到逻辑层面的设计之中,客观上的置换不是根据设计的需要进行更好的创造,我们只是利用这种客观的变换过程,来对逻辑设计进行评判和使用的一种解决方式而已。
那么“置换”具体是如何描述的呢?我们是否可以通过一种比较准确的定义来表达这样的一个概念呢?此概念是否能够正确地应用到我们的软件设计领域呢?
在数学概念中,置换就是在有限定义空间的满变换,而满变换所表示的意思如图1-3可以看出,定义域上每一个元素在值域上都有映射关系的结果。
图1?3
置换在数学中有很多实际的应用,例如在集合论中,一个集合的置换是从该集合映至自身的双射,又例如置换可以将元素的变换用矩阵的形式表示。
但是我们这里所提到的“置换”应该是一个更加广义的涵义,因为在计算机理论中,其替换的元素并不一定都是平等概念,其可能元素与元素之间是一种包含关系,或者是不同层次上的相互关系,例如上面提到的值和地址的置换与函数和函数指针的置换,以及类的抽象和继承等的置换,都是在不同层面进行的,而不同于数学矩阵概念上的“置换”,因此,这里的“置换”就是泛指的一种变换,其变换后的结果是:在逻辑意义上,通过对变换前的引用和变换后的引用在逻辑概念上等效。这样的变换结果就是一种置换,简单的说就是使用不同的表达形式,其在此的占位符在逻辑概念上是无关紧要的。
当然,我们这种广泛的表述方式也包含数学定义中的“置换”,虽然针对数学意义中的置换还有多种不同方式的表达,而这些表达方式也可能意义并非一致。
所以必须明确的说明,我们这里谈的置换是一个动态的过程,是一个动作。置换并非研究“静态”实体,而是研究一个“动态”的操作。所以,在我们使用的过程中,我们无法通过如值、地址、类等等可以通过静态的描述术语来表达,在我们的源代码中无法用一个符号来表示这就是置换,而且即使生搬硬套用一个符号来表示,其也无法融入到源代码中来表示。所以针对比如设计模式结构这样的方式,其实也是这种动态的描述,描述静态结构之间的相互关系以此指导我们的软件设计工作,因此我们在使用的时候,只是对一种“势”的使用。这种“势”就要求,我们的软件设计工作就是一种“平衡”的处理方式,在整个系统中通过多方面的取舍达到一个动态的平衡。
在逻辑意义上,使用直接地址来访问到的数据和通过指针访问到的数据是等效的,采用的方式不同,但是结果是等效的,这种用指针间接访问就是置换了直接地址访问,或者使用直接地址访问的数据置换了指针间接访问。
同理,对于一个继承关系来说,在此位置上,如果对父类的访问结果与对子类的访问结果是等效的,那么说明此继承关系可以进行相互置换。
当然对于置换来说,A置换B与B置换A虽然其操作名称都是置换,在逻辑概念上是等效的,但并不是表示其结果是相等的,也就是说,置换操作不具有交换性,A置换B的结果在物理上是不等效B置换A。
两种置换的复合还是置换,也就是说A置换B,B置换C,最后形成的A置换C也是成立的,说明这样的置换是可结合的。
但是置换具有传递性,也就是说A置换B,B置换C,那么一定能够推导出A置换C,例如在继承体系下,C继承于B,B继承于A,例如在函数参数的访问中使用B的引用就能够传递C进入,同时使用A的引用,也能够传递C进入。
继承表示一种运算关系,如果A继承于 B 则这种“置换”可抽象为一种运算A?B = B
抽象表示这种运算关系的反向运算, 如果A继承于B 则这种“置换”可表示为B?A = A
当然,我们也可以这样来看待类与对象的关系,他们应该是一个映射的关系,可以表示为“X”乘的关系,其扩展到时间和空间。应该是类型(属性+操作)在时间和空间上的某一系列变化的结果。
综上所述,目前已经被应用的设计方法中的绝大部分都是围绕可“置换”展开的,都体现了“置换”的基本概念所描述的思想。
1、 最基本的置换,值可置换(变量赋值)
2、 值与地址的可置换(指针)
3、 一个过程操作过程的可置换(函数),另外函数的参数也是一种置换方式。
4、 多态是函数置换的一种表示方式,是函数地址位置的置换。
5、 抽象和继承的可置换(类),目前是通过函数的可置换进行实际操作的。在类中使用private、protected、const等限制,并进一步定制所置换的部分。
6、 将这些可置换的函数分组,集合在一起形成接口,为什么要进行分组呢?因为这些可置换之间存在逻辑的联系(接口)
7、 需要对类型进行可置换(模板),泛型中的置换是既可以进行单独数据的置换,也能单独进行地址的置换,或者两者兼有。目前其数据成员无法特化,只能特化成员函数,而且成员函数特化可使用模板+继承来解决,例如如下的方式:
template <class Base>
class Derive:public Base{}
8、 typedef 对类型置换。模板与typedef实际上有很多相似之处,可以说在本质上是一回事,只是模板通过参数或配置方式来更改这种置换,是typedef的升级。
9、 对相同功能的函数进行名称的置换(函数重载),在STL中操作符重载实际上就是一种置换。
10、 对于分层,逻辑抽象实际上就是一种可置换的操作过程。是使用逻辑意义置换物理意义的过程。
11、 注册机制就是因为有地址的可置换,所以才能达到抽象的能力。
还存在其他更多的“可置换”的方面,所以设计就是寻找“可置换”的一系列操作的集合,好的设计可以通过这种可置换后的成本以及收益进行衡量,所以“可置换”可以作为衡量软件设计好坏的一个可行的标准之一。
可扩展性是软件设计的原则之一,是以适应软件系统的变化的适配的程度。可扩展性是软件拓展系统的能力,可扩展性非常重要,是现代软件系统重要的标志,一个软件系统如果欠缺可扩展性则代表其基本上走向死亡。根据上面我们对“可置换”的特征的分析,我们可以这样来说,设计就是一系列“置换”的设计过程。
“置换”并非是整体完整的替换过程,其中也存在“半置换”、“部分置换”等形式的存在,因为如果所站在一个整体的角度来说,“半置换”、“部分置换”是“置换”概念的必然的补充。
当然不能简单认为“半置换”、“部分置换”是一个意义不大的概念,其实“半置换”、“部分置换”的功能也是非常强大的,例如使用偏特化就是一个部分置换,这样能够在不同部分中进行置换,让设计的灵活性更加强大。
对于上面的置换, 应该分为两大类,一类是静态置换,例如typedef和class、template的置换,一类是动态置换就是赋值等的置换。
静态置换是一种在逻辑抽象上的置换,其是一种概念上的替换结果,静态置换不具有时间和空间属性,所以其最终的实现是通过动态置换来实现的。
动态置换包含了更多的实现细节,是将静态置换中的置换过程,在时间和空间上给予实现。
所以在层次上大体应该是这样的层次关系(图1-4所示),这个层次反映了我们的认识和实践的基本路径,这个层次过程表征就是我们设计过程的层次路径。
原文地址:http://blog.51cto.com/13832308/2132733