主页

索引

模块索引

搜索页面

传统可扩展架构-分层架构

分层架构是很常见的架构模式,它也叫 N 层架构:

1. N 至少是 2 层。例如,C/S 架构、B/S 架构
2. 常见的是 3 层架构(例如,MVC、MVP 架构)
3. 比较复杂的系统才使用4、5层架构

1. C/S 架构, B/S 架构

划分的对象是整个业务系统,划分的维度是用户交互,即将和用户交互的部分独立为一层,支撑用户交互的后台作为另外一层。

2. MVC 架构, MVP 架构

划分的对象是单个业务子系统,划分的维度是职责,将不同的职责划分到独立层,但各层的依赖关系比较灵活。例如,MVC 架构中各层之间是两两交互的

3. 逻辑分层架构

备注

划分的对象可以是单个业务子系统,也可以是整个业务系统,划分的维度也是职责。虽然都是基于职责划分,但逻辑分层架构和 MVC 架构、MVP 架构的不同点在于,逻辑分层架构中的层是自顶向下依赖的。典型的有操作系统内核架构、TCP/IP 架构。

https://img.zhaoweiguo.com/knowledge/images/architectures/expandabilitys/hierarchical1.png

Android 操作系统架构图

https://img.zhaoweiguo.com/knowledge/images/architectures/expandabilitys/hierarchical2.png

典型的 J2EE 系统架构

https://img.zhaoweiguo.com/knowledge/images/architectures/expandabilitys/hierarchical3.png

针对整个业务系统进行逻辑分层的架构图

备注

无论采取何种分层维度,分层架构设计最核心的一点就是**需要保证各层之间的差异足够清晰,边界足够明显,让人看到架构图后就能看懂整个架构**,这也是分层不能分太多层的原因。

分层架构之所以能够较好地支撑系统扩展,本质在于**隔离关注点(separation of concerns)**:

即每个层中的组件只会处理本层的逻辑。
比如说,展示层只需要处理展示逻辑,业务层中只需要处理业务逻辑,
  这样我们在扩展某层时,其他层是不受影响的,通过这种方式可以支撑系统在某层上快速扩展。
例如,Linux 内核如果要增加一个新的文件系统,则只需要修改文件存储层即可,其他内核层无须变动。
https://img.zhaoweiguo.com/knowledge/images/architectures/expandabilitys/hierarchical4.png

分层时要保证层与层之间的依赖是稳定的,才能真正支撑快速扩展。例如,Linux 内核为了支撑不同的文件系统格式,抽象了 VFS 文件系统接口

如果没有 VFS,只是简单地将 ext2、ext3、reiser 等文件系统划为 “文件系统层”,那么这个分层是达不到支撑可扩展的目的的。因为增加一个新的文件系统后,所有基于文件系统的功能都要适配新的文件系统接口;而有了 VFS 后,只需要 VFS 适配新的文件系统接口,其他基于文件系统的功能是依赖 VFS 的,不会受到影响。

分层结构的另外一个特点就是**层层传递**,也就是说一旦分层确定,整个业务流程是按照层进行依次传递的,不能在层之间进行跳跃。最简单的 C/S 结构,用户必须先使用 C 层,然后 C 层再传递到 S 层,用户是不能直接访问 S 层的。传统的 J2EE 4 层架构,收到请求后,必须按照顺序传递请求。

备注

分层结构的这种约束,好处在于强制将分层依赖限定为两两依赖,降低了整体系统复杂度。例如,Business Layer 被 Presentation Layer 依赖,自己只依赖 Persistence Layer。但分层结构的代价就是冗余,也就是说,不管这个业务有多么简单,每层都必须要参与处理,甚至可能每层都写了一个简单的包装函数。

分层架构另外一个典型的缺点就是性能:

因为每一次业务请求都需要穿越所有的架构分层,有一些事情是多余的,多少都会有一些性能的浪费。
当然,这里所谓的性能缺点只是理论上的分析,实际上分层带来的性能损失,
    如果放到 20 世纪 80 年代,可能很明显;
    但到了现在,硬件和网络的性能有了质的飞越,这点性能损失,在绝大部分场景下都可以忽略不计

主页

索引

模块索引

搜索页面