机制分析

 

发展独立思考和独立判断的一般能力,应当始终放在首位,而不应当把获得专业知识放在首位。如果一个人掌握了他的学科的基础理论,并且学会了独立地思考和工作,他必定会找到他自己的道路,而且比起那种主要以获得细节知识为其培训内容的人来,他一定会更好地适应进步和变化。

--- 爱因斯坦

 

当大家看完前面几章的分析以后,是否感觉其实还不大清楚,本章我与大家一起讨论一下我们在开发过程中使用的一些思想和方法,而这些思想和方法又与设计模式不在同一个层次,这些思想和方法我们完全可以不用谈到的设计模式来体现,也许这些思想和方法不是技巧了,不是一种具体的招式,而是贯穿于这个过程的一种规律。我给它取了一个名称叫做机制,虽然不是非常准确的表达,但是我想大家不是一定要吹毛求疵,如果大家有更好的名称,我会第一时间修改,在此表示感谢!

 

分层机制


我先讲的第一个机制就是分层,分层机制应该是耳熟能详,而且很多谈客也将这种机制作为炫弄的必谈内容。但是这里我想给大家从实际的开发环境中去讨论分层机制的得与失。从我们的实践中去看它的威力,也可以看看它的无奈。

为什么要分层呢?其实一个直接的原因是人的理解问题。或者说人类认识世界的方式导致。这里我不去仔细讨论这个哲学问题,只是简单说明一下:首先物理世界是非常复杂的,不是以我们的意志为转移的,而人类是可以去理解世界的,虽然我们无法完全一次性的理解这个无穷变化的物理世界,但是我们还是可以理解其部分特征,这些部分特征不是指集合中部分元素这样简单,而是构成一个体系,其内部有联系的部分特征。如何才能认识这些部分特征呢?那就是依靠我们的抽象能力,将具体的东西,去除于我们不关心的部分,留下一些固有的方法和方式,高度浓缩。在这个过程中还有一个方法就是独立性,比如大家经常说的物理独立性和逻辑独立性。于是经过不同层次的独立性我们就可以抽象出一个层次的特性,然后不断迭代进行。将这些迭代的过程张开以后就形成了分层的机制,如图3-1所示。

blob.png 

3-1

 

spacer.gif这些层次首先是我们人为的划分(带有强烈的主观逻辑性),因此所按照不同的划分方式,其层次并不一定唯一,而且不同的认识和理解其划分多少层,每个层次包含什么内容也是不尽相同的,因此层次这个东西是没有唯一的标准,就是因为没有唯一的标准,所以在实际开发中,我们的架构师的分层很难在开发人员中推广,因为说实话很多架构的分层所依赖的原因都远离我们的实际需要,都是不切实际的臆想。

别的不说,看看著名同时又可怜的七层网络模式,虽然划分的如此宏大,大量大师呕心作品,除去商业上的是是非非,我们客观来看看这个分层,其一就是划分的非常细致,分层很多,七层。对于一个体系来说,分层越多其效率也就越低下,分层越多其获益者能够垄断的方式就越少,同时开发人员也就越痛苦。所以分层并非越多越专业,实际上5层就足够。表达意思已经非常清楚了。而且七层分层也是只能按照当前的格局进行分层,最多有很少的一部分的前沿开拓,对于抽象来说,是对现有的特征进行抽象,而不是对未来可能的情况进行抽象。对未知的抽象就可能导致更多个人主观愿望,脱离了集体的认识领域,注定是要被人抛弃的,另外其实七层协议对每个层次上的独立,也是不能预测到未来的发展方向的,我事后诸葛说明一下:目前在2层和3层之间还有一个2.5层,而且这个2.5层融合了更多优秀的思想,能够完美的承上启下。后面我会详细讨论这一层对我们的影响和意义。

人们常常使用七层网络层次结构来表达分层的思想,但是在软件领域中,其分层不是按照这样明确的实际客观的网络结构来进行分层,而是采用一种主观上的划分,或者是主观与客观想混合的划分方式,其从人的理解层面来进行分层,从抽象到具体的分层,是一种归类的方式,然后再进行抽象,与网络七层结构的分层不太一致,那么这样两种分层谁是谁非呢?

分层的意义就是为了我们更好的理解,其一个目的就是解耦。利用层次化可以有效进行不同因素的分离,例如:

设计模式MVC分层的信息与呈现分离原则:

视图是信息的呈现,信息是稳定的,视图是易变的,不同运营商,不同角色有不同需求操作原子化,不组合。

ü 机机接口与人机接口分离

ü 接口与模型分离数据与处理分离

ü 接口协议栈与信息模型分离

ü 模型与实现分离

三者之间的关系和原则:

ü 适配:只有一个组件实现,但是该组件提供的各种接口方式来改变它的行为。

ü 替换:一个组件有多种实现,每个组件都符合该组件的接口规范,可提供多种实现,然后选择其中一个,或遵循组件规范开发个性的组件。

ü 扩展:扩展需要架构提供一些允许增加新组件的扩展点,添加的组件可以是特定产品或者架构内部的。

分层中提供的接口不能狭隘理解,其实每一个层次提供的接口就是向上提供的服务,要求层次间使用接口进行调用,这里所谈到的接口应该有两种不同的形式,一种是静态的API调用接口(不管是C++的虚函数接口还C语言的函数接口还是JAVA提供的接口)另一种就是动态的命令字,也就是消息。这两种划分的方式是有截然不同的效果以及优缺点。

分层必须遵循一些原则:

1、 每一个层次都使用接口形式向上提供服务,所以在使用的过程中,只能依赖于接口,而不能依赖于具体的实体,避免依赖于特殊处理,使用接口进行统一调用或消息发送和接收。

2、 原则上调用方式是从上到下调用,防止有引用向上的接口,或者进行向上的调用,如果存在向上调用则应该使用订阅者模式,解除循环依赖,保证各个层次间在物理和逻辑上都不存在耦合。

3、 同层之间的调用,最好集中在一个公共的功能模块中,本层的其他特性模块,依赖于这个公共的功能模块,另外越是靠经底层的层次,就越需要减少同层调用。

4、 防止跨层调用,如果存在这种情况,则表示我们的层次划分不清晰,接口需要进行清理或提炼,因为需要适当增加中间层。

防止层次调用中的跨层调用和下层对上层的直接调用。

ü 跨层调用将直接影响你的分层,可导致分层失败,层之间的独立性破坏。

ü 无法做到对层的替换,而且上层严重依赖下层的实现。无法做到移植。

ü 由于对下层的直接调用,可能会导致被绕过的层次的创建和释放无法按照正常顺序进行,导致系统异常。

ü 被绕过的层次无法进行控制和管理接口,并可能产生重复的代码和操作过程。

ü 下层对上层调用直接违反了上层抽象的意义,导致层次间混乱,一般情况为层次划分不正确。

ü 下层对上层调用,直接违反了解耦原则,导致上下层无法独立,耦合加剧。

对于上面需要解决下层对上层的调用和依赖的问题,可用“注册”的方式来解决(订阅者模式即使用此方法),使用不同的回调挂接在同一的列表中 ,通过公关功能模块进行不同的策略调用相关的回调挂接函数。为什么不希望跨层调用呢?或者方向调动呢?因为越向下其表达的是一个完备集合,提供的接口是此完备集合的子集,而越向上其需要越来越小的范围,那么可以通过接口来封装这样的范围紧缩的处理,如果不是这样就容易导致中间层的完备性的缺失。 

使用分层的效果:

1、 清晰了整个软件框架结构,不同的层次具有明确的功能定义,能够支撑团队的开发。

2、 不同的方案可以合并一起,通过中间层提升软件的复用。

3、 减少了层之间的耦合,使用接口(功能性)进行调用,大大减少了业务和硬件设备的强制依赖关系。

分层框架模式是最常用的框架模式,是一种通用的处理方案,但是如何更好的分层是需要具体场景具体分析,不能为了分层而分层,常见的错误做法就是无论什么系统都使用经典的三层或五层去套用,分层一定要有原因的,分层会降低执行效率,同时无谓的分层还增加了开发团队之间的配合难度。

也许对于硬件与软件之间的层次还有较多的方法进行抽象、隔离和解耦,但是对于再上面的层次中,我们又是通过哪些方法来进行抽象的呢?其抽象是否满足是深度呢?其实这些层次的抽象很容易产生中间层,例如网络层与链路层中间就产生了2.5层的mpls

与分层多对应的的有一种非常特殊的方式就是分级机制,而我们也经常将分层和分级进行统一或相互划分。

所谓的分级机制就是将不同速度或不同响应时间、不同的吞吐量、不同优先级权限按照一定的规则进行多级别的划分,在分级中,多体现的是不同级别如何匹配。就像流动的水,所以在此机制下,就有如何使用缓存,如何最优命中目标,其权限如何控制等。但分级和分层容易混淆,分层实际上包含了抽象与差异性的隔离,而分级主要是高速与低速,高优先级与低优先级权限等分离,但是在很多时候,分层与分级又混杂在一起,例如网络七层协议中,按照抽象出来的各个层次对应的功能特征,其实现方式有常常运用分级的思想,例如对于交换处理,可以使用硬交换也可以使用软交换。这两种处理其在层次上是同一层次,但是在实现处理上处于不同的级别中。

分层具有包含和抽象的特征,分级具有主要和次要、主干和分支等特征,所以分级更侧重于描述物理世界,分层更侧重描述逻辑世界。

有时候,在我们理解中分层在继承体系中常常是处于在同一层上。

分层中存在调用和被调用的关系,但分级存在协调的关系,所以一般表现为动态的特征,分级之间多采用消息这样的知会的方式,让接收者或者当前的状态,接收者通过仲裁和协调的方式,所以分级一般不使用静态调用的方式,而是通过协议、事件、消息进行通知和协调。

分级是纵向分区域,分层是横向分区域。

但是这样的方式好吗?或者说抽象的深度到了吗?这种通过物理的特性划分逻辑类是否暗示我们的抽象程度其实还不够深入,我们还依赖于物理特性,一旦物理特性发生变化,那么其逻辑特性也会发生变化,这也是一种耦合,其物理与逻辑独立性还不够充分。此时,我们应该学习学习UNIX操作系统的思想,其将一切I/O外设都看成一个文件,其操作都抽象为openclosereadwrite等操作,所以看看我们的设计,我们的物理与逻辑真的分离了吗?其实对于获取温度而言,其获取的完全可以看出一个个通道,对这些设备设置ID,形成一个回调的列表,当需要进行温度查询的时候,可以通过这些通道进行回调方式获取,如图3-2所示。

 blob.png

3-2

 

也许对于硬件和软件之间的层次还有较多的方式进行抽象、隔离和解耦,但是对于再上层的不同逻辑层进行划分,我们又是通过哪种方式来进行分层呢?其抽象也能够完全满足要求吗?而这些层与层之间,其实主要是逻辑定义而进行区分的,而这种假设一旦有变化,那么其层次划分就可能完全不一样了,所以经常大家会看到出现了中间层,例如网络七层中就出现了2.5层的MPLS的这一层次。

spacer.gifblob.png

其提供的接口其实应该更少,而为什么会形成这种金字塔方式的架构呢?信息隔离是其主要原因,越向上其所需要了解的知识应该更少,所以需要进行分层,而且分层还是金字塔方式的分层。其向上的信息会更进一步隔离汇总,认为其上层必须知道的结果才返回给上层,主要的方式,是最容易控制和维护的,因为上层进行命令的下发会更加规范的得到解析,具有中间转化层次更好满足这个需求,控制成本降低了才有利于起系统的推广和使用,同时也减少了使用者的学习成本,但是这样的分层很可能最后变成非常的低效,导致系统庞大,响应变慢,而这又反过来导致扩展或维护的成本增加。所以分层模式又称为官僚模式。

分层的优点:

1、 支持基于抽象程度递增的系统设计,使设计者可以把一个复杂系统接递增的步骤进行分解。

2、 支持功能增强,因为每一层至多和相邻的上下层交互,因此功能的改变最多影响相邻的上下层。

3、 支持重用,只要提供的服务接口定义不变,用一层的不同实现可以交换使用,这样就可以定义一组标准的接口,而允许各种不同的实现方法。

4、 提升整个系统的容量,随着分层的层次增加,其包含的信息也随之增加,于是可以将更多的信息纳入到此系统中,所以相应的容量获得提升。

分层的缺点:

1、 并不是每个系统都可以很容易地划分为分层的模式,甚至即便一个系统的逻辑结构是层次化的,出于对系统性能的考虑,系统设计师不得不把一些低级或者高级的功能综合起来。

2、 很难划到一个合适的,正确的层次抽象方法。层与层之间是不平等的关系,越往上走层次越高,数据流风格的各个过滤器和管道原则可以互换位置层是算法耦合,管道与过滤器是数据结构耦合。

3、 不同的分层之间,很难进行有效的融合。在一个较大的系统之中,当存在多个组件结合的时候,就可能存在不同体系不同方式的层次划分,而这也往往导致系统难于进行进一步有机的融合,只能通过不断的大量的接口进行平行的重合,这也导致了系统无法拉通进行合理的分层。例如操作系统和应用程序形成的体系层次划分完整以后,如果希望拉通融入网络的七层或者五层体系的时候,就变得非常的困难,就只能分离独立出网络特性组件,而在操作系统和应用程序的不同体系中都可能存在调用网络层次的不同层次上的接口。这反而导致了层次的混乱。其实在一个体系中,“山头主义”、“部门墙”都是在一个系统中无法拉通整个分层划分标准导致的一种违反分层原则出现的现象,这种情况出现的原因就是不同分层无法融合导致的,这种情况反而大大减低了分层带来的好处,危害了体系的健康发展。所以所谓的大统一,其实就是想办法解决这些分层的融合。

4、 分层导致了信息的膨胀,可能会因为层次的不断划分,而导致系统容许的信息量呈现非线性的增加,从而导致系统失控,难于被掌握。

好,下面我们来看看这个中间层次与上下两层之间的关联以及存在的原因。

在系统科学中,层次关系是局部与整体关系的重要内容。如同系统结构一样,层次也是一个难以准确定义的概念,可以理解为元素整合为整体的涌现等级。亚里士多德提出“整体大于部分之和”,那么这个大于的特性究竟是什么呢?系统科学把这种整体才具有,孤立部分极其总合不具有的性质称为整体涌现性(whole Emergence)涌现性就是组成成分按照系统结构方式相互作用、相互补充相互制约而激发出来,是一种组分之间的相干相应,即结构效应。涌现性又可理解为非还原性或非加和性,但任何整体都具有加和性,比如质量。系统性是加和性与非加和性的统一,都是整体属性,所以整体性、系统性并不一定是涌现性。涌现性是系统非加和的属性,“整体大于部分之和”与“整体小于部分之和”这样的整体与部分差值不等的部分就是涌现。

所以层次关系中的涌现特点,导致了分层的出现。在系统科学中,分层并非是人的好恶一样的主观决定,而是因为涌现出新的特点,所以我们需要进行合理的分层。在软件设计中,我们也找到一种评价其分层的好的方式,就是判断是否在不同层次是存在不同的特性。比如在逻辑层和物理层独立并划分层次以后,其涌现的特点最为明显的是“可置换性”,在物理层中,硬件特点其描述的是无法更改替换的电信号(至少在目前的电子计算机时期是这样的),而一旦逻辑层形成高级分层以后,“可置换”就能够达到通过中间层次,通过逻辑的关系进行不断的间接处理,并且让上层的处理越来越灵活,越来越更加表达抽象的意义。当然除了具有“可置换性”以外还有其他的特性,这里就不进行进一步的深入分析了。

在系统科学的观点中,层次是从元素到系统整体质的根本质变过程中呈现出来的部分质变序列中的各个阶梯,是一定的部分质变所对应的组织形态,对于系统科学来说,无论是系统的形式和保存,还是系统的运行和演化,等级层次结构都是复杂系统最合理的或最优的组织方式,或最少的空间占有,最有效的资源利用或最大的可靠性。同时,系统是朝着增加复杂性方向演化的,层次的增多总意味着复杂性的增加。

所以对于这种最为熟悉的机制,其也包含太多的内容,更有很多还未明白其理,虽然其应用广泛,但是我们却往往没有正确的使用,所以机制对于我们来说还非常的陌生和不确定性。