架构设计系列之常见架构(一)

news2024/9/21 20:24:42

本部分对常见架构进行简单的说明。

一、三层架构之经典 MVC

经典的 MVC 架构(Model-View-Controller)架构是软件系统架构设计中的经典,它将应用程序分为三个主要部分:

  • 模型(Model)
  • 视图(View)
  • 控制器(Controller)

这样的三层架构有助于实现业务逻辑的分离,提高代码的可维护性和可扩展性。

二、 CQRS(命令查询职责分离)

命令查询职责分离模式(Command Query Responsibility Segregation,CQRS)是一种软件架构模式,它通过从业务上分离修改(Command:增、删、改,会对系统状态进行修改)和查询(Query:查,不会对系统状态进行修改)的行为,使逻辑清晰,提高系统的可维护性和灵活性。

1 、优点

  • 业务逻辑清晰:将修改和查询操作分开,使业务逻辑更加清晰。命令负责修改状态,而查询负责获取信息,降低系统复杂性
  • 可维护性增强:通过将写模型和读模型分离,可以独立演化和优化两者。提高了系统的可维护性,开发人员可以更容易地理解和修改两个模型
  • 扩展性:支持根据系统需求独立扩展命令和查询部分,这种灵活性使得系统更容易适应不断变化的需求
  • 更好的性能优化:通过专门优化读模型,可以更好地满足查询性能的需求,有助于提高系统的整体性能

2 、不足

  • 结构复杂:引入两个独立的模型(读写),使得系统结构复杂度高,维护和理解这两个模型之间的关系可能需要更多的工作
  • 冗余代码:由于存在独立的读写模型,可能导致代码冗余,特别是对于一些共享的业务逻辑,这需要谨慎的设计和维护,以避免冗余
  • 性能问题:涉及多次数据库操作,可能导致性能问题,特别是在需要频繁进行读写操作的情况下,需要根据具体情况进行性能优化
  • 工作流不直观:将任务分解为多个步骤,可能导致工作流难以理解,尤其是对于新加入的开发人员,文档和培训对于确保团队对工作流的理解至关重要
  • 缺乏标准化:并没有广泛的标准,团队在实践中需要根据自身需求进行调整,可能缺乏一致性和规范性

3 、总结

CQRS 是一个特定场景下有益的架构模式,但在引入时需要仔细权衡其优缺点。在对系统的可维护性、可扩展性和性能有较高要求的情况下,CQRS 可能是一个有价值的选择。然而,对于简单的应用程序,引入 CQRS 可能会增加不必要的复杂性。在实践中,团队应该根据具体情况慎重考虑是否采用 CQRS 。

三、六边形架构

六边形架构(Hexagonal Architecture)也称为端口适配器模式,是 Alistair Cockburn 在 2005 年首次提出的一种软件架构模式。其主要目标是将应用程序的核心逻辑与特定的输入/输出技术解耦,使其能够更灵活的应对变化和演化。

1 、三个原则

明确分层层次(Explicitly separate Application,Domain,and Infrastructure)

在六边形架构中,明确分离应用程序(Application)、领域(Domain)和基础设施(Infrastructure)是关键的设计原则,这种分离使开发者将关注点分离开,每一层都可以独立变化而不影响其他层,提高了系统的可维护性、可测试性和可扩展性。

  • 应用程序层(Application Layer)
    • 责任:包含应用程序的业务逻辑,负责协调领域层和基础设施层的交互,不包含具体的业务规则,而是将请求委托给领域层进行处理
    • 实现:通常由应用服务组成,提供用例的实现,负责接收外部请求、处理输入数据、协调领域层的操作,并调用适当的基础设施服务
  • 领域层(Domain Layer)
    • 责任:包含系统的核心业务逻辑和领域模型,这是系统的灵魂,包含了问题域的概念、规则和约束
    • 实现:由实体(Entities)、值对象(Value Objects)、聚合(Aggregates)、领域服务(Domain Services)等构成,协调工作,实现业务规则,确保系统的行为符合领域的要求
  • 基础设施层(Infrastructure Layer)
    • 责任:负责处理与外部系统的通信、数据库访问、日志记录等与具体技术相关的事务,包含所有与技术实现有关的组件
    • 实现 :包括数据库访问层、外部服务通信层、日志记录、配置等,这些组件对系统的业务逻辑是透明的,通过接口与应用程序层和领域层进行交互

依赖关系指向领域层(Dependencies are going from Application and infrastructure to the Domain)

确保领域层保持独立性,不依赖于具体的应用程序逻辑或基础设施技术,提高系统的可测试性、可维护性和可扩展性。

技术上,就是 Application 和 Infrastructure 都不能直接互相调用对方的功能或者操作,只有经过 Domain 的接口才能沟通,确保 Domain 部分具有完整的独立性,不受 Application 和 Infrastructure 变更的影响,从而保持稳定,这样的代码结构易读、易管理、易维护。

  • 依赖关系的方向
    • 应用程序层向领域层的依赖:应用程序层包含用例的实现,负责协调系统的操作并调用领域层的服务
    • 基础设施层向领域层的依赖:基础设施层包含与技术实现相关的组件,领域层不应该直接依赖于这些具体的技术实现,而是通过接口定义领域层所需的服务,并由基础设施层来实现这些接口
  • 实现方式
    • 领域服务接口:在领域层中定义接口,描述领域服务的行为,这些接口是应用程序层和基础设施层依赖的抽象 ➡️ 如果领域层需要使用某种外部服务,可以在领域层定义一个接口,然后在基础设施层中实现这个接口
    • 依赖反转:通过依赖反转原则,应用程序层和基础设施层不直接依赖于领域层的具体实现,而是依赖于领域层定义的接口和抽象,这会让领域层能独立于其他层进行演化,不受具体实现细节的影响
    • 测试驱动开发:将依赖关系的方向设计成从应用程序和基础设施指向领域,有助于采用 TDD,通过在应用程序层和基础设施层编写测试用例,并通过模拟或替代领域层的具体实现,可以更容易进行单元测试,确保领域层的正确性

使用端口和适配器隔离边界(We isolate the boundaries by using Ports and Adapters)

六边形架构使用端口和适配器模式来隔离系统的边界,以提高系统的可测试性、可维护性和灵活性,目标是将业务逻辑与外部环境解耦,让系统的各个部分更容易替换、测试和理解

  • 基本概念
    • 端口:定义系统与外界通信的接口,表示系统的一种能力或服务,通常通过接口来表示,定义系统对外提供的服务,不关心具体的实现,只关注服务的契约
    • 适配器:连接系统内部和外部的组件,负责将系统内的数据结构或接口转换成外部系统期望的形式,是外部环境和系统内部通信的桥梁,确保系统的核心业务逻辑不受业务环境的影响
  • 具体应用
    • 内部端口和适配器:将应用程序划分为核心业务逻辑(Application)和外部环境(Infrastructure)两部分,内部端口表示系统对外部环境提供的服务,而内部适配器则负责将内部数据结构适应外部环境的需求
    • 外部端口和适配器:外部端口表示系统对外部环境的依赖,而外部适配器则将外部环境的服务适配成系统内部期望的形式,使系统的核心业务逻辑不直接依赖于具体的外部实现,而是通过端口和适配器与外部环境进行通信

2 、特点

  • 对称性:系统的设计围绕着一个中心的应用核心组件,所有的交互都必须通过这个中心
  • 隔离性:应用程序的核心组件被一层薄的适配器包围,使得它对外部环境的变化免疫
  • 可插拔性:系统可以通过改变其适配器来更改接口,并适应不同的上下文

3 、组成部分

  • 应用核心:整个架构的心脏,包含了应用程序的业务逻辑和领域模型,不依赖任何特定的外部元素,只关注应用程序的核心功能
  • 端口:是应用程序核心向外提供的接口,定义了应用程序如何与外部世界进行通信
  • 适配器:用于连接应用程序核心和外部世界的栋梁,实现了端口的具体行为,并将请求路由到正确的位置

4 、好处

  • 灵活性:当外部环境发生变化时,只需要修改适配器即可,而无需触及应用程序的核心
  • 测试友好:可以轻松模拟和替换适配器,从而更容易测试应用程序的核心部分
  • 低耦合:应用程序的核心部分与外部环境完全解耦,使其更易于维护和扩展

5 、不足

  • 设计复杂度高
  • 需要花费更多时间进行需求分析和设计
  • 学习曲线比较陡峭,需要具备一定的软件设计知识

6 、总结

六边形架构是一种有助于提高代码代码质量和维护性的设计方式,但它也有一定的学习成本和实施难度。在实际应用中,可以根据具体项目的规模和复杂程度以及团队的技术能力,灵活运用此模式。

四、洋葱架构

洋葱架构(Onion Architecture)是由 2008 年,Jeffrey Palermo 提出,它在端口和适配器架构的基础上将领域放在应用中心,将用户用例和基础设施放在外围,这种设计思路类似于六边形架构,都是通过适配器代码将应用核心从对基础设施的关注中解放出来,以避免基础设施代码渗透到应用核心之中,使得框架和中间件需要改变替换的时候更加轻松,不会影响到核心领域。

1 、设计原则

  • 依赖性:洋葱架构中的圆圈代表不同的责任层,进入越深越接近领域和业务规则,外圈代表机制,内圈代表核心领域逻辑,外层依赖于内层,而内层对外圈一无所知
  • 数据封装:每个圈层封装内部实现细节,向外层公开接口,在内层定义抽象接口,在外层提供具体实现,确保专注于领域模型,而不必过多地担心实现细节。运行时,可以使用依赖注入框架,将接口和实现连接起来
  • 关注点分离:应用系统被分为多个层级,每一个层级都有一组职责,并解决不同的关注点
  • 耦合性:低耦合性,一个模块和另一个模块交互时不需要关注另一个模块的内部具体实现,所有的内部层级不需要关注外部层级的具体实现

2 、架构分层

  • 应用服务层:负责协调请求步骤的服务,不应该有任何业务逻辑,应用服务与其他服务交互来满足客户请求
  • 领域服务层:负责保持领域逻辑和业务规则,所有的业务逻辑应该作为领域服务的一部分来实现。领域服务由应用服务协调,服务于业务用例。不是简单的 CRUD 服务
  • 领域模型层:封装属性和实体行为
  • 基础设施层:在洋葱架构中的最外层,负责与外部世界交互,不解决任何领域的问题,没有任何逻辑
  • 可观察性服务层:负责监控应用,可以用于数据收集(指标、日志、痕迹)、数据存储、可视化等

3 、优势

洋葱架构建立在一个领域模型上,各层之间通过接口交互,其设计思想是在领域实体和业务规则构成架构的核心部分时,尽可能将外部依赖性保持在外:

  • 提供灵活、可持续和可移植的架构
  • 各层之间没有紧密耦合,且有关注点的分离
  • 所有代码都依赖更深的层或者中心,提高可维护性
  • 提高整体代码的可测试性,单元测试可以在单独的层创建,不会影响其他的模块
  • 框架/技术可以容易改变而不影响核心领域

4 、不足

  • 设计复杂性:多个端口和适配器需要额外的设计工作且增加了系统复杂度
  • 维护困难:洋葱架构的系统非常复杂对应的维护难度也比较高

5 、总结

洋葱架构适用于大型、复杂的应用程序,对于需要长期维护和演进的系统,其设计理念有助于降低变更的风险,提高系统的可靠性和可扩展性,在具体应用时,可以根据项目规模和团队技术水平做出适当的调整。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1311911.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

内存问题(一)——内存概述

一、内存泄漏(Memory Leak) 是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。 二、一般内存泄露的方式 常发性内存泄漏:发生内存泄…

Java实现快速排序及其动图演示

快速排序(Quicksort)是一种基于分治思想的排序算法。它通过选择一个基准元素,将数组分为两个子数组,其中一个子数组的所有元素都小于基准元素,另一个子数组的所有元素都大于基准元素,然后递归地对这两个子数…

C_11练习题答案

一、单项选择题(本大题共20小题,每小题2分,共40分。在每小题给出的四个备选项中,选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) 以下叙述中正确的是(C)A.C语言不是一种高级语言 B.C语言不用编译就能被计算机执行 C.C语言能够直接访问物理地址和进行位…

Process On在线绘制流程图

目录 一.ProcessOn 1.1.介绍 1.2.直接网上使用 二.绘制门诊流程图 三.绘制住院流程图 四.绘制药库采购入库流程图 五.绘制OA会议流程图 今天就到这里了哦!!!希望能帮到你哦!!! 一.ProcessOn 1.1.介绍 ProcessOn(流程&#…

【强化学习-读书笔记】多臂赌博机 Multi-armed bandit

参考 Reinforcement Learning, Second Edition An Introduction By Richard S. Sutton and Andrew G. Barto强化学习与监督学习 强化学习与其他机器学习方法最大的不同,就在于前者的训练信号是用来评估(而不是指导)给定动作的好坏的。 …

Windows中使用pthread线程库

由于时间成本,不想使用Windows线程API,因此想用pthread线程库;但pthread是Linux默认的POSIX线程库,Windows中并不自带,需要自己配置。 因为pthread遵循POSIX标准,因此其在Windows中使用应该和Linux中大同小…

JAVA:深入探讨Map的多种遍历方式

1、简述 在现代编程中,Map(映射)是一种常见的数据结构,用于存储键-值对。在许多编程语言中,Map提供了灵活的数据组织方式,但为了充分发挥其功能,我们需要了解多种遍历方式。本文将深入探讨Map的…

国际刑警组织推出新的生物识别系统

2023 年 11 月 29 日,国际刑警组织发布了一份有关创建生物识别工具的新闻稿,至少在意大利,该工具似乎已经陷入沉默,但让我们看看为什么我们会对这个东西感兴趣。 国际刑警组织的新闻稿用了整整一段时间来讨论与隐私相关的问题&am…

【sqli靶场】第六关和第七关通关思路

目录 前言 一、sqli靶场第六关 1.1 判断注入类型 1.2 观察报错 1.3 使用extractvalue函数报错 1.4 爆出数据库中的表名 二、sqli靶场第七关 1.1 判断注入类型 1.2 判断数据表中的字段数 1.3 提示 1.4 构造poc爆库名 1.5 构造poc爆表名 1.6 构造poc爆字段名 1.7 构造poc获取账…

Android Studio实现俄罗斯方块

文章目录 一、项目概述二、开发环境三、详细设计3.1 CacheUtils类3.2 BlockAdapter类3.3 CommonAdapter类3.4 SelectActivity3.5 MainActivity 四、运行演示五、项目总结 一、项目概述 俄罗斯方块是一种经典的电子游戏,最早由俄罗斯人Alexey Pajitnov在1984年创建。…

保障事务隔离级别的关键措施

目录 引言 1. 锁机制的应用 2. 多版本并发控制(MVCC)的实现 3. 事务日志的记录与恢复 4. 数据库引擎的实现策略 结论 引言 事务隔离级别是数据库管理系统(DBMS)中的一个关键概念,用于控制并发事务之间的可见性。…

【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数

本文涉及的基础知识点 二分查找算法合集 动态规划 题目 给你一个下标从 0 开始的 m x n 整数矩阵 grid 。你一开始的位置在 左上角 格子 (0, 0) 。 当你在格子 (i, j) 的时候&#xff0c;你可以移动到以下格子之一&#xff1a; 满足 j < k < grid[i][j] j 的格子 (i,…

聊聊分布式数据库TDSQL的技术架构

大家好&#xff0c;我是飞哥&#xff01; 咱们很多读者都是在互联网公司工作&#xff0c;大部分同学会有一种认知偏差&#xff0c;总以为互联网的业务对技术的要求是最高的。但其实不然。 比如在对延时的要求上&#xff0c;高频量化交易就比互联网的延迟要求要高得多。在数据库…

家政服务小程序预约上门,让服务更便捷

随着人们生活节奏的加快&#xff0c;家政服务行业越来越受到人们的欢迎。为了满足市场需求&#xff0c;提高服务质量&#xff0c;家政公司需要开发一款预约上门的家政服务小程序。本文将详细介绍如何制作一个预约上门的家政服务小程序。 一、登录乔拓云网后台 首先&#xff0c…

springoot集成kafka

1.常见两种模式 2.高可用 和 负载均衡 组内:消费者 一个只能消费一个分区 组外:消费者消费是订阅者模式

Element的安装以及基本使用

Element是基于Vue的网站组件库&#xff0c;用于快捷构建网页 像上面这样的样式 官网地址 Element - 网站快速成型工具 安装 npm i element-ui -S 装包命令 npm install babel-plugin-component -D 安装好之后会在package.json里面显示版本 在node_modules中会自动初始化一个 …

选择排序-排序算法

思路 选择排序&#xff08;Selection sort&#xff09;的主要思路是&#xff1a;在要排序的区间内找到一个最大的元素&#xff0c;将它放到数组的最后一个位置&#xff0c;然后在剩余的未排序区间内找到一个最大的元素&#xff0c;将它放到数组的倒数第二个位置。以此类推&…

涵盖多种功能,龙讯旷腾Module第六期:输运性质

Module是什么 在PWmat的基础功能上&#xff0c;我们针对用户的使用需求开发了一些顶层模块&#xff08;Module&#xff09;。这些Module中的一部分是与已有的优秀工具的接口&#xff0c;一部分是以PWmat的计算结果为基础得到实际需要的物理量&#xff0c;一部分则是为特定的计…

2023iEnglish学习成长营结营 助力自主阅读习惯养成

iEnglish智能英语学习解决方案日前消息,2023年最新一期的365天和1000天“iEnglish学习成长营”顺利结营。据悉,截至今年12月,完成365天和1000天每天坚持不低于30分钟的英语原版阅读人数分别累计突破15万人和2万人。而当前,21天、100天、365天以及1000天四种不同目标和意义的iEn…

中文分词演进(查词典,hmm标注,无监督统计)新词发现

查词典和字标注 目前中文分词主要有两种思路&#xff1a;查词典和字标注。 首先&#xff0c;查词典的方法有&#xff1a;机械的最大匹配法、最少词数法&#xff0c;以及基于有向无环图的最大概率组合&#xff0c;还有基于语言模型的最大概率组合&#xff0c;等等。 查词典的方法…