建筑学的设计原则也应当成为软件系统设计的指导原则。
第一种情况
这也就是最为熟知的情况。客户端向第N层发出请求,而第N层不能独立完成请求,需要调用第N-1层所提供的服务,第N-1层同样需要他的下级,也就是N-2层所提供的服务。如此往复,直到第2层和第1层。
第1层可以独立完成自己的任务,它将执行的结果返还给第2层。第2层得到第1层的结果之后,便能够继续完成自己的任务了,它会把执行的结果继续向上,也就是第3层传递。如此反复,一直到第N-1层和第N层。
图12、在有N个层次的架构中,请求(Request)沿着层次自上向下传递,结果(Result)自下向上传递。
系统的客户端只知道第N层,它向第N层发出请求,并且从第N层接到结果,客户端并不知道其他层次的存在。参见下图。
图13、客户端只知道第N层,而不知道其他层次。
第二种情况
这第二种情况代表了自下至上的通讯,称为通知(Notification)。这一系列的行为开始于第1层,这一层通过处理后,将通知向上传给第2层,继续向上传递到第3层,一直到第N-1层和第N层为止。参见下图。
图14、在有N个层次的架构中,Notification沿着层次自下向上传递。
使用过USB设备的读者知道,一旦把USB设备插入到计算机中的时候,USB驱动软件立刻就会发现设备被激活,并通知设备的设备操作软件,设备操作软件便会启动。这一系列的行为就是Notification自下向上传递的过程。
在第一种情况中,请求首先向下传递,然后结果逆向传递,形成一个环形。在第二种情况中,Notification的传递是单向的。
第三种情况
这一种情况与第一种情况相似,只是仅涉及到一部分的层次而已。
首先客户端向第N层发出请求,而第N层不能独立完成请求,需要调用第N-1层所提供的服务,第N-1层同样需要他的下级,也就是N-2层所提供的服务。如此往复,直到第J层为止。
第J层可以独立完成自己的任务,而不再需要J-1层。它将执行的结果返还给第J+1层。第J+1层得到第J层的结果之后,便能够继续完成自己的任务了,它会把执行的结果继续向上,也就是第J+2层传递。如此反复,一直到第N-1层和第N层。参见下图。
图15、在有N个层次的架构中,Request向上传递到某个中间层次就停止了,Result从那里向下传递。
同样,客户端只知道第N层,而不知道其他层次的存在。
第四种情况
这种情况描述的是Notification自下向上传递的过程,只是第二种情况涉及到全部的N各层次,而这里仅涉及到一部分的层次而已。参见下图。
图16、Notification自第1层向上传递到某个中间层次就停止了,通讯过程是单向的。
首先,全部的行为开始于第1层,这一层通过处理后,将通知向上传给第2层,继续向上传递到第3层,一直到第J层为止,不会再向上传递。
第五种情况
此种情况涉及到两个层次结构,两个结构之间相互通讯,常常称作协议层次结构(Protocol Stacks)。在下面的图中,左边的第N层发出请求,这个请求向下传递,经过N-1层,…第2层直到第1层。
这个时候,请求被接着传递给右边的第1层,然后沿着层次结构向上传递,经过第2层,第3层等等,一直到第N-1层和第N层。
图17、请求从左边的第N层向下传递到第1层,然后传递到右边。
执行的结果自右边的第N层开始向相反传递,经过右边的第N-1层,N-2层,…第2层、第1层,然后返回到左边的第1层,再沿着左边的层次结构向上传递,经过第2层,第3层,…到达第N-1层,回到第N层。
图18、结果从右边的第N层向下传递到第1层,然后传递到左边。
两端的客户端A和B都只知道各自的第N层,而不知道其他层次,它们会认为在两个层次之间存在一个联结,其实这个联结是虚拟的,是通过其他层次进行的。
图19、客户端A发出请求给左边的第N层,经过中间的过程之后,到达右边的第N层,然后传递到右边的客户。
TCP/IP的层次结构
TCP/IP的设计显然是依循层次原则设计的,参见下图。
图20、TCP/IP的设计图。
:
无循环依赖原则(ADP)
在层次的相互依赖关系中,不允许出现循环依赖关系。比如下面的图中显示了从第N层到第N-1层的依赖,从第N-1层到第J层的依赖,从第J层到第2层的依赖,从第2层到第1层的依赖;这都是没有问题的。但是图中还有一个从第J层到第N层的依赖关系。这就造成了一个循环的依赖关系,而这种循环依赖关系时应当避免的。
图21、出现了循环依赖关系。
假象每一层都由一个木板代表,木板一层压着一层摆放。上层的木板就会依赖于下层的木板,这就是依赖关系。这样的依赖关系是不可能循环的,因为欧几里德几何学不会允许。如果硬要设计出循环依赖关系的话,就只好伪造几何学,参见下图。
图22、不可能的几何:在三维欧几里德空间中无法实现这样的几何结构。