这一块对我来说是一个新的领域,所以刚开始看起来有些吃力。希望能够慢慢的进入状态。也许需要依靠笔记的帮忙。在我的学习中,学习笔记占有很大的地位,他不但是记录,更重要的是,他帮助我更深入的思考。不写笔记我会感觉没有学到东西。
1.1.1. 层
可以将系统划分为子任务组,每个子任务组在一个特定的抽象层次上。
1. 例子
ISO7层模型。
2. 语境
一个需要分解的大系统
3. 问题
假设有一个系统,它明显的混合了底层与高层的问题。
强制条件:
1) 一个地方的更改,被限制在某组件或某层内,不会扩散到整个系统。
2) 接口应该是稳定的,甚至可以用标准件来限定。
3) 系统的各个部分应该可以替换,组件可以被其他的实现方法来替换而不影响系统有的其他部分。则可能基于优秀的接口定义。
4) 以后可能有必要建立其他系统,这些系统具有和当前设计的系统具有同样的底层问题。
5) 相似职责应该可以分组,以提高可理解性和可维护性。每个组件应该是内聚的(如何提高组件的内聚性?让它只做自己的事情,不要越权。)
6) 没有标准的组件粒度?为什么?
7) 复杂组件需要进一步分解。是的,可以在组件内分解成子组件。如果还是太复杂,则可以考虑将它分成几个层。
8) 跨组件边界可能影响性能。
9) 在接口定义明确的情况下,系统可以由一个程序员组来创建。
4. 问题
将系统划分为N层,从最低抽象层次开始,一直向上增加,直到第N层。
5. 问题
层模式的主要结构特征是第J层的服务只被第J+1层使用——层之间没有更进一步的依赖关系。每个独立层都要防止较高层次直接访问。
6. 动态特性
下面是各个场景:
1) 一个客户端向层N发送请求,但是层N无法完成服务,它需要调用N-1层的服务来完成这个服务。以此类推,N-1调用N-2,N-2调用N-3……直到调用的最底层完成服务,然后向上反馈服务调用结果。这个描述的自顶向下的通信。一个这样的请求可能对应多个底层的服务调用。
2) 描述自底向上的通信——一般是收到一个底层信号,比如驱动检查到有一个收到一个消息,然后逐层向上传输。第一个一般称为请求,这个可以成为通知。同样,几个通知可能会合成一个更高级的通知。
3) 请求或通知只需经过整个系统的一个子集。比如,层n-1可以提供服务。或者,底层的通知第2层就可以处理。
4) 包括两个相互通信的协议堆栈。
7. 实现
1) 为把任务分组而定义抽象准则。抽象准则确定有多少抽象层。
用户可见元素
特定应用模块
公共服务层
操作系统接口层
操作系统
硬件
2) 根据抽象准则定义抽象层数。每个抽象层对应模式中的一个层。如果抽象层过于复杂,则可能要进一步分解。层数的控制:过少则少数层过于复杂,过多会导致不必要的开支。
3) 给每个层命名并制定他们的任务。要给他找一个好的,简短的名字。如果你的名字很长,或者很难起名字,则可能说明你对这一层的思考不到位,这一层还需要进一步分解或者调整。要提高层的内聚性。如果采用自顶向下,则最高层是整个系统的功能,而其它层都是他的助手。
4) 指定服务。最重要的原则是层间要彼此严格分离。没有一个组件跨越多于一个层。括号中的话理解不深(把较多的服务层放在高层比底层好。这是由于开发人员不用学习之友大量细微差别的原语,他们甚至可以在并行开发期间更。扩展高层以适合更宽广的应用面,而基础层保持细长。这种现象也称为“逆向重用金字塔”)。
5) 细化分层。重复执行步骤1~4。这样才可以获得一个更好的层次结构。
6) 为每个层指定一个接口。尽量使用黑盒方法来——即J-1层对层J是黑盒,它只对外提供接口,而外面不知道它的内部结构和实现(其实也就是面向接口编程而非面向实现编程)。设计一个平展(flat)接口以提供所有层J服务,并可能把这些接口封装在一个外观(facade)对象之中。?(什么是平展接口?是否是没有层次关系的接口?)
7) 构建独立层。不但要设计合理的层间结构,层内部的结构也要合理。如果层过于负责,可以考虑将层分解为多个组件。如果还过于复杂,则要考虑生成一个新的层。组件的设计可以使用其他的模式优化。
8) 指定相邻层间通信。包括推模式,拉模式,以及回调。
9) 分离邻接层。这个没有完全理解。往往高层关系相邻的底层,底层不关心用户的身份。这意味着只能单路连接:修改层J被改变了的服务的界面和语义保持稳定,层J中的改变可以忽略层J+1的存在和标识(我感觉这里的翻译有些问题。这里的大意应该是,如果保持层J的接口不变(服务的界面和语义),这个时候,层J的更改可以忽略层J的存在。应该是这样的分离。)。
对于自底向上的通信,可以使用回调函数且保留自顶向下的单路耦合。高层向底层注册事件回调函数(这个我使用过)。这个时候可以考虑使用反应器模式和命令模式。???不知道是翻译的原有,文章的描述相当晦涩。明明一个很明确的东西,通常说的相当复杂。
10) 设计一种错误处理策略。对于层式体系结构来说,错误处理在处理时间和编程工作方面成本较大。错误处理一个原则:尽量底层处理。即便是要高层处理,也要转化为更高层能够理解的错误类型。另外,要减少错误类型,能合并的,尽量合并。
8. 以解决的例子
TCP/IP。
9. 变体
1) 松散分层系统。层间没有严格的约束。这种方案丧失了可维护性,得到的是灵活性和性能。这个要慎用。通常见于基础结构中。
2) 通过继承分层。底层作为基类实现,高层作为底层的一个子类,所以他可以向基类请求服务。优点是高层可以根据需要修改底层的服务。缺点是集成关系把高层与底层紧紧捆绑在一起。层间的耦合性增加。
10. 已知应用
1) 虚拟机,在操作系统和硬件上增加了一个间接层。
2) API,
3) 信息系统,
11. 效果
优点:
1) 层的重用。如果一个独立层体现了一个良好定义的抽象,并且有良好定义和文档化的接口,该层就可以在多个语境中重用。
2) 标准化支持。
3) 局部依赖性。降低层发生更改对其他层的影响。
4) 可替换性。
不足:
1) 更改行为的重叠。一个改动可能要贯穿整个层次结构。
2) 降低效率。
3) 不必要的工作。
4) 难以认可层的正确粒度。层数过少不足以发挥这种模式的可重用性,可更改性,可移植性潜力。过多,则会引入不必要的复杂性和层间分离的冗余。