本章将讨论将逻辑组件分组之后分布在不同的层,这样的一种应用。层集中关注单个逻辑和功能组件,不考虑组件的物理存放位置。逻辑层可以放在不同的物理层,也可以放在同一个物理层。本章将会交给你如何将你的应用分解为不同的逻辑层,如果选择合适的功能布局,应用如何支持多种客户端类型。
分清楚逻辑层和物理层的区别是非常重要的,逻辑层描述的是功能逻辑和组件的分组,物理层描述的是功能和组件在不同机器上的部署分布。尽管每个都包括相同名字的层:表现层、业务层、服务层、数据访问层,但是要记住只有物理层代表物理的分离。在同一个物理层部署多个逻辑层是很常见的。
逻辑层的设计
不管你设计什么类型的应用,是否有用户界面,或者只是一个暴露服务(不要和应用的服务层混为一谈)的服务性应用,你都可以将应用分为不同的逻辑组。这些逻辑组就叫做层。逻辑层帮助区分组件之间的不同类型的任务,使得设计一个可重用的组件变得更加容易。
表现层,业务逻辑层,数据访问层
下图显示了一个简化的,这些逻辑层的高层表现,以及它们之间的关系。
这些逻辑层可以分布在不同的物理层,也可以分布在一个物理层。如果有分开部署的需要,在设计的时候就要考虑这些问题。
在上图中显示了常用的三层:
-
表现层。是一些用户接口,和业务逻辑层进行通信。
-
业务逻辑层。是系统的核心,包装了全部的业务逻辑。
-
数据访问层。主要是对数据源的操作,对上屏蔽了数据源操作的细节。数据库源可能是数据库,也可能是文件,也可能是其他的系统提供的服务。
服务和分层
从高层来看,以服务为基础的解决方案要看成是有很多服务组成,例如彼此之间通过消息来通行。概念上来讲,服务也是方案中的一个组件。但是,在内部,每个服务又是由多个组件组成的。
服务层
如果一个应用必须为其他应用提供服务,或者是支持客户端直接实现功能,常用的方法就是使用一个服务层暴露应用的业务功能。服务层是客户端访问应用的另外一种形式。
在上面的方案中,用户可以通过表现层访问应用,直接和业务层组建进行通信。同时,外部客户端和其他系统也可以通过服务层和系统进行通信。这样就允许应用更好的支持多种客户端类型。
在某些情况,表现层也会通过服务层和业务逻辑层进行通信。当然,这也不是绝对的。如果应用的表现层和业务逻辑层物理部署在同一个物理层,他们就可以直接通信。
分层架构的设计步骤:
当开始设计应用的时候,你首先集中在高层的抽象级别上,通过将功能组分到不同的层开始。接下来要为不同的层定义通信的公共接口,这需要依赖于你正在设计的应用类型。一旦你定义了逻辑层和接口,你一定要决定应用如何部署。最后给层之间的交互选择通信协议。尽管你的结构和接口会演化多次,尤其是你使用敏捷开发,这些步骤保证你在过程的开始考虑了重要的方面。典型的步骤包括:
-
选择分层策略
-
决定你需要的层
-
定义如何分布层和组件
-
确定你是否需要折叠层
-
确定层之间的交互规则
-
确定那些需要跨层的关注点
-
定义层之间的交互接口
-
选择部署策略
-
选择通信协议
1 选择你的分层策略
分层代表将应用的逻辑按照角色和功能分为不同的组件。使用分层的方法可以提高应用的可维护性,在性能需要提高的时候很容易扩展。分组可以有很多的方式。但是,将应用分为太少或者太多的层会增加不必要的复杂性,会降低整体的性能、可维护性、灵活性。决定合适的分层粒度是分层策略的关键的第一步。
你还需要考虑是单纯的逻辑分层,还是有潜在的物理分层存在。跨层会影响本地的性能,尤其是中间有物理层的跨越。但是,增加了应用整体的伸缩性和灵活性。另外,分层利于性能优化,可以优化单个层,而不影响相邻的层。
在分层的情况下,部署在同一物理层上的逻辑层中间的交互和操作是在同一个进程中的,允许你使用高效的通信方式,例如:通过组建接口直接调用方法。但是,为了提高可维护性,确保将来的灵活性,你要小心维护封装和层之间的松散耦合。
逻辑层部署在不同的物理层,相邻逻辑层之间的通信将会发生在网络环境,你要确保你的设计选择了合适的通信方式,考虑到了网络延迟和维护层之间的松散耦合。
考虑你的应用是部署在同一个物理层,还是分离的物理层,在分层策略中也是很重要的。为了保持灵活性,通常要保持层之间的交互是松散耦合的。既保持了部署在同一物理层的时候的高性能,又在需要的时候允许你部署在不同的物理层。
调整分层方法会增加复杂度,可能会增加预先估计的开发时间,但是如果实现的正确,将会很大的提高应用的可维护性、可扩展性、和灵活性。你一定要权衡可重用性和逻辑层之间的松散耦合,相对于带来的复杂性和性能的影响之间的利弊。很小心的考虑如何分层,层之间如何交互,确保在性能和灵活性之间有一个好的平衡。通常来说,通过分层设计,如果可以获得灵活性和可维护性,要比不分层带来的性能提升,更加重要。