企业应用架构模式中的层次模型简介

937 阅读9分钟

企业对外提供服务,通常借助于软件应用。比如交易零售系统,用来提供购买商品的服务,这里就涉及到交易数据,这些数据会被用户“反复”的产生、查看,而且随着服务时间增长,应用本身也会面临困难

  • 业务逻辑。业务本身是有一定的逻辑性的,但会经常出现特殊的业务场景,导致出现"无逻辑"的复杂业务
  • 数据增长。应用本身会产生大量的数据,他们每天会被大量的用户同时操作、同时访问,需要确保最终数据的表现是符合预期的
  • 三方依赖。企业应用本身会与其它企业应用集成,与不同的企业应用集成面临不同的风格
  • 开发效率。一方面必须快速的开发出来,一方面又要考虑后续发展的可能性,如果不做后续发展的考虑,灵活性不够,会带来额外的复杂性,影响系统发展,但这额外的考虑又会可能“挑战”开发进度,影响效率
  • 应用性能。响应时间、吞吐率、负载、容量、可伸缩性

架构模式基本概念

架构

架构是一种主观上的东西,是对系统设计的一些可共享的“主观理解”,可共享性表现在系统中主要的组成部分以及他们之间的交互关系。对架构的定义能够统一的内容有两点:

  1. 最高层次的系统分解
  2. 系统中不易更改的决定

模式

模式描述了一个在我们周围不断重复发生的问题以及该问题解决方案的核心,这样能够一次又一次的使用该方案而不用做重复的劳动

使用分层分解复杂软件系统的优劣

层次模型致力于将企业应用组织成不同的层次,并协调各层次之间的关系

  • 优势:一层可以作为一个有机整体,无需理解其它层次;一层是可以替换的,只要保证层次的服务一样;只要构建好了一层就能够为很多上层同时提供服务;分层之后有利于标准化;层次之间的依赖性降低
  • 劣势:层次不能封装所有的东西,比如数据库加了一个字段,会造成级联修改;过多的层次会影响性能

三层架构的系统

  • 表现层:处理用户与软件的交互,比如HTML界面
  • 领域层:处理业务逻辑,根据表现层得到的数据,进行验证、计算以及确定使用哪个数据源进行存储
  • 数据源层:与数据库、消息系统、事务管理器等交互,大多数就是持久化数据

这里的层次是逻辑上的,不一定是物理上的隔离,所有层可以在1个服务器上,也可以是多个物理机

组织领域逻辑的方式

有三种组织形式 事务脚本、领域模型、表模块。

他们之间并不互相排斥,可以在事务脚本中处理部分领域逻辑,同时使用表模块或者领域模型来处理剩下的部分

事务脚本

使用过程来组织业务逻辑,每个过程处理来自表现层的单个请求。简单的来说就是从表示层获得输入、进行校验和计算处理、将数据存储到数据库中以及调用其它系统的操作等等

  • 优点:使用过程模型简单易懂;能够与简单数据源层很好的协作;事务边界清晰
  • 缺点:多个事务要做相同的事情或者类似的动作时,拆分提取公共的子例程棘手,容易导致程序结构杂乱无章

领域模型

合并了行为和数据的领域的对象模型(每个类都有行为和数据,类之间交互来完成任务)。简单来说就是每个对象都承担一部分相关逻辑

  • 优点:能够利用现成的技术来组织日趋复杂的领域逻辑(前期准备好了,后期好使用)
  • 缺点:使用复杂、数据源层复杂

表模块

处理某一数据库表或视图中所有行的业务逻辑的实例,它处于领域模型和事务脚本的中间地带

  • 优点:能够与已有部分更好的衔接,在过程的基础上增加了更多的结构,更容易移除冗余逻辑
  • 缺点:无法组织与领域模型一样的细粒度逻辑结构技术

不同领域组织方式区别示例

案例:对于一个给定的合同,不同的产品种类有不同的收入确认算法,需要计算给定合同的收入

事务脚本与领域模型的区别:

  • 事务模型会有一个收入服务,它的计算收入方法会包含所有的业务逻辑,内部调用的所有下层方法仅仅负责把数据值返回给事务脚本任务
  • 领域模型会有多个对象,每个对象都会向前传递一部分行为给另一个对象,直至最终创建了结果

表模块与领域模型的区别:

  • 领域模型对每一个合同都有一个相应的合同类的实例
  • 表模块是只有一个公共的合同类实例

领域模型与表模块的细分

独立出一个服务层放在领域模型与表模型之上,服务层本身有3种形式

  1. 仅传递上层到下层,所有的实际行为都在下层。此时它用于提供更易于使用的API,也可以作为切入点增加事务封装和安全检查
  2. 在服务层使用事务脚本的形式组织所有的业务逻辑,使得下层的领域对象变简单
  3. 控制器-实体 形式。它折中于1和2,将单个事务或用例所特有的逻辑置于事务脚本之中

可以在有要的时候才加服务层,如果加了也要最小化

从架构模式看领域逻辑访问数据库的方式

以数据库的表结构为基础,每张表对应一个类,这种类为数据库访问提供了’入口‘。

应用程序其它部分就不需要关心SQL

入口使用方法有两种

  1. 行数据入口,为查询语句的每一行产生一个它的实例(简单来说查询的列不同,返回的VO不同)
  2. 表数据入口,数据库中的每个表仅用一个对象来管理(简单来说不同的查询,返回同一种结构的记录集)

数据映射器

在简单的领域模型中,模型本身和表相当一致,这时可以让领域对象本身去负责数据库的存储过程(也称作活动记录),它实际就是以行数据入口开始,把领域逻辑加入到类中,但是当领域模型复杂时,入口可以解决一些问题,但是这其实是让数据库方案和领域方案冗余在一起,导致部分入口域和领域对象域的转换,使得领域对象变得复杂,这时可以使用数据映射器,它来处理数据库和领域模型之间的所有存取操作,并且允许二者独立变化,使二者完全独立

工作单元

使用活动记录能够解决简单的读取和存储操作,但是涉及到读取同时修改再存储等复杂操作,必须保证数据库的一致性,这种情况就可以工作单元解决。
工作单元用来充当数据库映射的控制器,它会跟踪所有从数据库读取对象以及任何形式修改对象,同时也负责重新提价到数据库。

简单的情况是由领域自己来完成,复杂情况则是交给了工作单元来做

结构映射模式

处理关系映射

表结构之前一般存在着 一对多,多对多这种结构,对象也需要处理好这种映射关系,方法则是在对象中使用一个标识域来保持对象之间的关系特性,并通过查找这些值来保持对象引用与关系键之间的映射。

并不是所有的关系都需要外键与关系域这种映射,如果值对象很小,可以使用序列化的方式直接存储到关联对象的一列中

对象的继承关系在表结构中的映射

对象本身存在继承关系,这个时候将这种结构映射到表中通常有以下三种方式:

  1. 单表继承,为一个层次中的所有类建立一张表
  2. 具体表继承,为每个具体的类建一个表(每张表包含类的所有字段)
  3. 类表继承,为这个层次中的每一个类建一张表(每张表不包含父类的字段)

类表继承通常需要多个连接,损失了性能;具体表该表很麻烦,一旦父类变更,所有的表都得改动;单表存在着空间浪费,单表过大也影响性能,但是修改容易而且不用连接

根据应用场景选择具体方式

表现层的视图模式

模板视图:在网页结构中编写表现层,并允许在网页中嵌入标签,用以指明网页中的动态内容需要导向哪里,比如JSP 转换视图:将领域层返回的数据转换到表现成对应的结构位置上,比如根据后端的json数据反映到对应的样式表单

单阶视图与两阶视图

单阶视图:为每个屏幕准备一个视图组件,视图提取领域数据并把它返回到HTML网页中 两阶视图:首先根据领域数据产生一个逻辑屏幕,然后发往HTML网页。每个屏幕本身都已经有了一个第一阶段的视图,而程序中只有一个第二阶段的视图

两阶视图可以决定把什么样的HTML网页用在什么地方,另外多端(PC/PAD/手机)通过不同的逻辑屏幕能够展示不同的外观视图

附录

<企业应用架构模式> 1-4 章