基于子层集和数据模型层次结构使用示例的层叠应用程序架构






3.81/5 (7投票s)
本文将探讨不同类型应用程序的分层架构示例。
1. 应用数据
应用数据位于数据模型、数据容器中,可以从外部数据源加载。
1.1. 应用数据模型是数据结构及其处理操作的集合。
1.2. 应用数据容器
- 显示应用数据的可视化表单
- 内部应用数据资源——文本、XML、图像、二进制文件;包含应用设置的文件、包含应用元数据的文件、包含国际化数据资源的文件
- 应用程序使用的数据传输通道中的数据流
1.3. 外部数据源是数据资源和外部应用程序。
1.3.1. 外部应用程序是数据存储(持久化数据存储、基础设施数据存储)。
它们执行数据存储功能。数据存储的例子包括服务器数据库、FTP服务器、目录服务、电子邮件存储系统。
1.3.2. 外部应用程序是瞬态数据源。它们不是数据存储。瞬态数据源从持久化数据存储、其他瞬态数据源检索数据,或使用自身业务逻辑算法生成数据。例如:Web服务、消息队列。
1.3.3. 数据资源是操作系统资源(OS 注册表数据、OS 和硬件设置、USB/COM/LPT 端口)、本地文件以及本地网络中的共享文件,包括桌面数据库文件。
1.4. 应用数据组。
应用数据组包括外观应用数据、内部应用数据、外部应用数据以及应用边界的数据。请参见图 2-4。
2. 单层应用模式和结构
2.1. 单层应用程序的结构包含 3 个主要组
- 分层组的功能由一组隔离的层组成;每一层实现其特定的功能;相邻层之间单向交互。
- 横切组的功能可被所有应用程序层使用。
- 数据流组的功能使用数据映射操作在应用程序数据模型之间传输数据,使用数据绑定操作在数据模型和可视化界面之间绑定数据,使用数据序列化操作在通过数据传输通道与其他应用程序交换数据时序列化/反序列化数据;数据交换是双向的;数据流组的功能定义了应用程序中使用数据模型的边界。
2.2. 单层应用程序可以呈现为两种模式
- 应用程序层交互模式
- 应用程序数据模型之间的数据传输模式、数据模型数据与可视化界面控件数据之间的绑定模式、通过数据传输通道与其他应用程序交换数据时的序列化/反序列化模式。
3. 在单层应用程序中使用分层架构
n 层(n>1)架构内的功能被组织成水平层。每一层在应用程序中都有特定的角色和职责。每一层都关联一个或多个数据模型。层功能可以实现为独立的专用类,也可以实现为数据模型类中的方法。
外观层用作访问应用程序功能的接口,供 n 层应用程序的其他层或外部应用程序使用。
逻辑层实现应用程序逻辑。
持久化层实现访问持久化数据存储的功能。
4. 应用层结构
应用程序的每一层都包含一组子层——外观子层和一个或多个功能子层。子层是实现一组功能操作的功能块。
外观子层是实现层外观的功能块,较高应用程序层通过该外观子层访问该层功能。
逻辑子层是实现层逻辑的功能块。
数据访问子层是实现访问外部数据源功能的功能块。
5. 多层应用程序
多层应用程序由一组单层应用程序和外部数据源组成。每一层都可以实现在单独的软件平台上。例如:第 1 层 - Java,第 2 层 - JavaScript + Angular
在 3 层应用程序中,第 1 层专注于与外部消费者交互,第 2 层专注于与业务逻辑和外部数据源交互。
第 3 层是外部数据源。
6. 应用层与数据模型的关系
每一层的的功能都使用一个或多个数据模型。在某些情况下,一个数据模型可以被多个应用层使用。
7. 应用层与数据资源的关系
每一层的的功能都使用其特有的数据资源。
7.1. 对于外观层,这些是 OS 注册表、应用程序设置文件、资源文件和应用程序元数据文件、USB/COM/LPT 端口。
7.2. 对于逻辑层,这些是业务数据文件存储——例如,XML 和 CSV 文件。
7.3. 对于持久化层,这些是桌面数据库。
8. 应用层与应用层之间的数据交换
8.1. CLR 对象(Microsoft .net 平台)或 Java 对象(Java 应用程序)用于应用程序层之间的数据交换。
8.2. 数据传输对象用于多层应用程序的层之间或不同应用程序之间的数据交换。数据传输对象的主要数据格式是 XML 和 JSON。
9. 功能操作的类型
应用程序功能实现为一组操作。
操作是子层的接口,提供对较高子层、较高层或外部应用程序的子层功能的访问。
9.1. 视图逻辑操作由可视化表单控件使用。
9.2. 表示逻辑操作实现外观层的逻辑。
9.3. 应用逻辑操作实现应用程序特定的业务规则,协调业务逻辑和外部数据访问操作,并作为访问逻辑层功能的接口。
9.4. 领域逻辑操作实现应用程序无关的业务规则。
9.5. 查询操作实现从持久化数据存储中选择数据的功能。它们代表 CQRS 原则中的查询部分。
9.6. 命令操作实现更改持久化数据存储中数据的功能。它们代表 CQRS 原则中的命令部分。
9.7. 数据传输操作在与外部数据源交换数据时使用。
9.8. 持久化外观操作是接口,用于从较高应用程序层访问持久化层功能。它暴露了一个粗粒度的接口。
9.9. 持久化逻辑操作是处理持久化数据存储中数据的逻辑的实现。
9.10. 在读/写本地数据资源时,应用程序使用 OS 数据读/写功能。
10. 外观层结构和功能
外观层用于与应用程序数据的外部使用者交互。数据使用者是用户和其他应用程序。外观层由外观子层、逻辑子层和数据访问子层组成。
外观子层
- 对于 GUI 应用程序,实现可视化界面,这是一组可视化表单
- 对于 Web 服务,实现数据传输接口,该接口允许外部数据消费者通过数据传输通道访问 Web 服务
- 用于调用表示逻辑操作
逻辑子层
- 实现表示逻辑操作,用于外观层和逻辑层应用程序逻辑之间的交互
- 例如,这是 ASP.NET MVC 技术中的一组控制器。
当应用程序中没有逻辑层时,外观层使用数据访问子层。实现查询、数据读/写和数据传输操作。
11. 逻辑层结构和功能
逻辑层实现应用程序逻辑。逻辑层由外观子层、逻辑子层和数据访问子层组成。
外观子层
- 调用逻辑层功能从外观层进入的入口
- 检查用户对逻辑层功能的访问权限
- 实现逻辑层中的通用错误处理算法
- 管理数据访问子层中命令操作的事务
- 数据访问子层中命令操作的输入数据验证
- 逻辑子层领域逻辑操作的输入数据验证和输出数据过滤
- 逻辑层操作的日志记录
逻辑子层实现领域逻辑操作。
数据访问子层实现查询、命令、数据读/写和数据传输操作。
12. 持久化层结构和功能
持久化层用于处理持久化数据存储。持久化层由外观子层、逻辑子层和数据访问子层组成。
外观子层是用于从较高应用程序层访问持久化层功能的接口。外观子层可以使用数据访问对象模式实现。
逻辑子层是处理持久化数据存储中数据的逻辑的实现。ORM 框架可用于逻辑子层。在使用直接 SQL 查询时,逻辑子层可以使用持久化管理器对象。
数据访问子层用于与持久化数据存储交互。数据访问子层是一组数据库连接对象,在与数据库交互时,它们使用 ODBC/JDBC 驱动程序和 OLE DB 提供程序中实现的功能。
13. 操作与应用层之间的关系
子层 / 边界 | 对象 / 接口 | 操作 | Data | 注释 |
外观层 | ||||
应用边界 | 可视化界面 | 数据在可视化表单中显示 | 对于 GUI 应用程序 | |
数据传输接口 | 数据流 | 对于 Web 服务 | ||
外观子层 | 可视化表单 | 视图逻辑操作 | 视图模型 | 对于 GUI 应用程序 |
Web 服务对象(Web 服务的服务器端部分) | 用于与外部消费者交互的数据传输操作 | 内部数据传输模型 | 对于 Web 服务 | |
逻辑子层 | 视图呈现器 | 表示逻辑操作 | 视图模型 | 对于 GUI 应用程序 |
数据传输呈现器 | 表示逻辑操作 | 内部数据传输模型 | 对于 Web 服务 | |
数据访问子层 | 持久化服务 | 查询操作 | 持久化模型 | 用于外部数据源,如持久化数据存储 |
目录服务 | 用于与目录服务交互的数据传输操作 | 目录数据模型 | 用于外部数据源,如目录服务(LDAP、Active Directory) | |
消息服务 | 用于与 Web 服务和消息代理交互的数据传输操作 | 外部数据传输模型 | 用于外部数据源,如瞬态数据源 | |
OS 数据读/写功能 | 用于与外部数据源(如文件和 OS 资源)交互的数据读/写操作 | 数据流 | 用于外部数据源,如文件和 OS 资源 | |
逻辑层 | ||||
外观子层 | 应用逻辑对象 | 应用逻辑操作 | 领域模型 | |
持久化模型 | ||||
外部数据传输模型 | ||||
逻辑子层 | 领域逻辑对象 | 领域逻辑操作 | 领域模型 | |
数据访问子层 | 持久化服务 | 查询操作 | 持久化模型 | 用于外部数据源,如持久化数据存储 |
持久化服务 | 命令操作 | 持久化模型 | 用于外部数据源,如持久化数据存储 | |
目录服务 | 用于与目录服务交互的数据传输操作 | 目录数据模型 | 用于外部数据源,如目录服务(LDAP、Active Directory) | |
消息服务 | 用于与 Web 服务和消息代理交互的数据传输操作 | 外部数据传输模型 | 用于外部数据源,如瞬态数据源 | |
OS 数据读/写功能 | 用于与外部数据源(如文件和 OS 资源)交互的数据读/写操作 | 数据流 | 用于外部数据源,如文件和 OS 资源 | |
持久化层 | ||||
外观子层 | 数据访问对象 | 持久化外观操作 | 持久化模型 | |
逻辑子层 | ORM 框架、用于直接 SQL 查询的持久化管理器对象 | 持久化逻辑操作 | 持久化模型 | |
数据访问子层 | 数据库连接对象 | 用于与 SQL Server 数据库交互的数据传输操作 | 外部数据传输模型 | 用于持久化数据存储,如 SQL Server 数据库 |
数据库连接对象 | 用于与桌面数据库交互的数据传输操作 | 外部数据传输模型 | 用于持久化数据存储,如桌面数据库 | |
应用边界 | 网络接口 | 数据流 | 用于持久化数据存储,如 SQL Server 数据库 | |
OS 数据读/写功能 | 数据流 | 用于持久化数据存储,如桌面数据库 |
14. 分层应用架构示例
考虑到使用的操作集和外部数据源的类型,可以描述一组基本应用程序架构。
14.1. 通用应用程序架构
14.2. 数据源与数据消费者之间的数据传输模式
14.3. 应用架构示例
15. 基于换热器计算示例的应用架构与用例的关系
用例由一个或多个场景组成。每个场景都是完成用例所需的步骤列表。
为了将用例场景的步骤与应用程序功能相关联,需要引入应用程序逻辑单元的概念。
应用程序逻辑单元是应用程序逻辑功能在用例场景中使用的一个元素(这是逻辑层外观子层中的应用程序逻辑操作)。
如果应用程序功能是使用一组用例设计的,那么设计的结果将是一组应用程序逻辑单元,它们实现了该应用程序所有用例的功能。
如果使用命令模式来实现应用程序逻辑单元,那么可以通过一组命令对象来描述应用程序的所有用例。每个应用程序逻辑单元将使用单独的命令对象来实现。
命令模式非常适合将业务逻辑定义的用例显式地表示到应用程序代码中的目标。
以 GUI 应用程序为例,考虑换热器计算作为用例场景。
换热器计算算法可以作为通过一组可视化表单实现的。在第一个表单上,用户输入计算的初始数据,在最后一个表单上,显示计算结果。在每个表单上,都会调用一个或多个应用程序逻辑单元。
步骤 1. 用户打开表单 1,在此输入换热器计算的初始数据。这是应用程序逻辑单元 11(检索换热器计算算法中使用的参考数据集)。
步骤 2. 在表单 1 上,用户输入初始数据并启动计算算法。这是应用程序逻辑单元 21(启动换热器计算算法;然后将计算出的换热器列表保存到数据库)。
计算完成后,表单 1 关闭,表单 2 打开,显示计算出的换热器列表。这是应用程序逻辑单元 22(从数据库检索计算出的换热器列表)。
步骤 3. 在表单 2 上,用户选择一个合适的换热器,然后转到表单 3 查看其参数。这是应用程序逻辑单元 32(有关选定换热器的信息已输入数据库)。
表单 2 关闭,表单 3 打开,显示选定换热器的参数集。这是应用程序逻辑单元 33(从数据库检索选定换热器的参数)。
步骤 4. 在表单 3 上,用户查看选定换热器的参数。关闭表单 3 时,所有未选中的换热器将从数据库中删除。这是应用程序逻辑单元 44。
因此,用例场景由应用程序逻辑单元集的功能决定。外观层可以使用各种技术实现,但应用程序逻辑单元的功能将保持不变。
历史
- 2020 年 10 月 28 日:初始版本。
- 2020 年 11 月 24 日:编辑了第 9、12、13 章