DDD之六边形架构(Hexagonal Architecture)

领域驱动设计系列文章,点击上方合集↑

六边形架构(Hexagonal Architecture),也被称为端口和适配器架构(Ports and Adapters Architecture),是一种软件架构模式,用于构建可测试、可维护和灵活的应用程序。

1. 简介

六边形架构的设计思想源于Alistair Cockburn在2005年提出的“六边形关系图”理论。在这个理论中,软件系统被视为一个六边形,其中有三组组件构成:核心业务逻辑(Domain),输入和输出端口(Ports)以及适配器(Adapters)。这些组件通过一系列接口进行交互,实现内部的业务逻辑,并通过端口和适配器与外部系统进行交互。

  • 上图来自《实现领域驱动》这本书

2. 主要组件和原则

  1. 核心业务逻辑(Domain):核心业务逻辑是应用程序的核心部分,其中包含领域对象、实体、值对象、领域服务等。它独立于具体的技术实现,通过领域模型去描述和解决业务问题。

  2. 输入和输出端口(Ports):输入和输出端口定义了应用程序与外部世界的交互接口。输入端口用于接收来自外部系统的请求,输出端口用于向外部系统发送结果或状态更新。这些端口提供了抽象层,使核心业务逻辑与具体的外部依赖解耦。

  3. 适配器(Adapters):适配器是连接输入和输出端口与具体实现的桥梁。它们负责将外部世界的请求转换为适合核心业务逻辑处理的数据,并将结果适配为外部系统能够理解的形式。适配器可以是数据库、消息队列、外部服务库或任何其他与外部系统进行交互的方式。

在六边形架构中,核心业务逻辑位于六边形的中心,它不依赖于具体的外部实现。输入和输出端口围绕核心逻辑,提供与外部系统的交互接口。适配器将请求和响应合理地转换为适合核心逻辑的形式。这种架构模式使得我们可以更容易地替换、测试和调整外部依赖,因为核心逻辑与外部实现解耦。

3. 构建步骤

  1. 定义领域模型和核心业务逻辑:通过DDD的原则,识别并定义核心业务领域,并建立一个独立于技术实现的领域模型。

  2. 定义输入和输出端口:识别应用程序与外部系统的交互点,并设计相应的端口接口。这些端口应该抽象、可扩展和可测试。

  3. 实现适配器:根据具体的外部系统,实现适配器将外部请求转换为领域模型可以理解的格式,并将结果转换为外部系统可以处理的格式。

  4. 配置依赖注入(Dependency Injection):通过依赖注入,将适配器注入到核心业务逻辑中,确保它们能够无缝地协作。

  5. 编写测试:通过单元测试和整体测试,确保核心业务逻辑与外部系统的交互正常,并满足业务需求。

4. 具体代码演示

假设我们正在开发一个电商应用,需要实现商品管理的功能,包括添加商品、查询商品等操作。我们将使用Spring Cloud作为微服务框架,将核心层和外围层分离,使用适配器进行交互。

4.1 核心层的设计

首先,我们在核心层定义商品的领域模型和业务逻辑:

public class Product {private String id;private String name;private double price;// getters and setters
}public interface ProductService {Product addProduct(Product product);List<Product> getAllProducts();Product getProductById(String id);
}

4.2 外围层的设计

接下来,我们设计外围层,定义与外部系统的交互接口。

@RestController
@RequestMapping("/api/products")
public class ProductController {private final ProductService productService;public ProductController(ProductService productService) {this.productService = productService;}@PostMappingpublic ResponseEntity<Product> addProduct(@RequestBody Product product) {Product addedProduct = productService.addProduct(product);return ResponseEntity.ok(addedProduct);}@GetMappingpublic ResponseEntity<List<Product>> getAllProducts() {List<Product> products = productService.getAllProducts();return ResponseEntity.ok(products);}@GetMapping("/{id}")public ResponseEntity<Product> getProductById(@PathVariable String id) {Product product = productService.getProductById(id);return ResponseEntity.ok(product);}
}

4.3 适配器的实现

我们使用Spring Cloud中的Feign客户端作为适配器,与其他微服务进行通信。

@FeignClient(name = "product-service", url = "http://localhost:8080") 
// 这里假设商品服务的URL为http://localhost:8080
public interface ProductServiceFeignClient {@PostMapping("/api/products")Product addProduct(@RequestBody Product product);@GetMapping("/api/products")List<Product> getAllProducts();@GetMapping("/api/products/{id}")Product getProductById(@PathVariable String id);
}

4.4 依赖注入与配置

最后,我们通过依赖注入将适配器注入到核心业务逻辑中,使用Spring Cloud进行配置管理。

@Configuration
public class ProductServiceConfiguration {@Beanpublic ProductService productService(ProductServiceFeignClient productServiceFeignClient) {return new ProductServiceAdapter(productServiceFeignClient);}
}

4.5 配置文件

在Spring Cloud中,还需要配置各个微服务的相关信息。

spring:application:name: product-serviceproduct-service:server:port: 8080

通过以上代码演示,我们将商品管理的核心业务逻辑与外部系统的交互逻辑进行了解耦,并支持了系统的扩展和替换。核心层的设计遵循领域驱动设计的原则,外围层通过适配器与外部系统交互,实现了六边形架构。

当我们需要对商品管理进行扩展时,可以通过修改核心层的代码来实现。当需要修改与外部系统的交互方式时,只需要修改适配器的实现即可,而不需要改动核心层的代码。

5. 结语

通过六边形架构,我们可以将关注点分离开来,提高系统的可测试性、可维护性和可扩展性。同时,该架构也使得领域驱动设计中的概念更加清晰,并促进了团队间的协作和集成。


关注微信公众号:“小虎哥的技术博客”,让我们一起成为更优秀的程序员❤️!

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

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

相关文章

C++ 简介、基本语法、数据类型、变量、常量

一、C简介&#xff1a; C是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言。支持过程化编程、面向对象编程和泛型编程。C是C的一个超集&#xff0c;任何合法的C程序都是合法的C程序。 面向对象开发的四大特性&#xff1a; ◆ 封装&#xff08;Encapsulat…

nginx基础组件的使用

文章目录 一、Nginx 的相关组件介绍1.1、ngx_palloc相关源码1.2、ngx_array组件的相关源码1.3、ngx_array的数据结构1.4、ngx_cycle简介和相关源码1.5、ngx_list相关源码1.6、ngx_list 的数据结构 二、Nginx 组件的使用2.1、makefile的编写2.2、ngx_pallocngx_array的使用2.3、…

SpringBoot:ch03 yml 数据绑定示例

前言 Spring Boot 提供了强大的配置能力&#xff0c;通过 YAML 文件进行数据绑定是一种常见且便捷的方式。在本示例中&#xff0c;我们将演示如何利用 Spring Boot 的特性&#xff0c;通过 YAML 文件实现数据绑定。借助于 YAML 的简洁语法和结构化特性&#xff0c;我们能够轻松…

基于文心一言AI大模型,编写一段python3程序以获取华为分布式块存储REST接口的实时数据

本文尝试基于文心一言AI大模型&#xff0c;编写一段python3程序以获取华为分布式块存储REST接口的实时数据。 一、用文心一言AI大模型将需求转化为样例代码 1、第一次对话&#xff1a;“python3写一段从rest服务器获取数据的样例代码” 同时生成了以下注解 这段代码首先定义…

单链表(数据结构与算法)

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…

口袋参谋:只用一招,提前规避差评!请看具体操作步骤

​如何提前规避差评&#xff1f;至少99%的商家都不知道该怎么做&#xff0c;剩下的1%还是我刚教会的。 宝贝的评价直接影响宝贝转化&#xff0c;特别是新品链接。 10个好评也挽回不了一个差评对产品的致命打击&#xff0c;差评就像一个重磅炸弹&#xff0c;威力足够能让你的转…

RabbitMQ安装说明

注意: 本次安装以 CentOS 7为例 1、 准备软件 erlang 18.3 1.el7.centos.x86_64.rpm socat 1.7.3.2 5.el7.lux.x86_64.rpm rabbitmq server 3.6.5 1.noarch.rpm 2、安装Erlang rpm -ivh erlang-18.3-1.el7.centos.x86_64.rpm 3.、安装RabbitMQ 安装 rpm -ivh socat-1.7.3.2-…

2.4G无线收发芯片 XL2400P使用手册

XL2400P 系列芯片是工作在 2.400~2.483GHz 世界通用 ISM 频段的单片无线收发芯片。该芯片集成射 频收发机、频率收生器、晶体振荡器、调制解调器等功能模块&#xff0c;并且支持一对多组网和带 ACK 的通信模 式。发射输出功率、工作频道以及通信数据率均可配置。芯片已将多颗外…

深眸科技以自研算法+先进硬件,创新打造AI视觉一体化解决方案

工业视觉软硬件一体化解决方案&#xff1a;是以工业AI视觉技术为核心&#xff0c;通过集成工业相机等视觉硬件、电控系统和机械系统等自动化设备以及算法平台等软件应用&#xff0c;为工业自动化降本增效提质。 深眸科技为进一步巩固和加强技术领先优势&#xff0c;创新打造的…

【精选】构建智能木材计数系统:深度学习与OpenCV完美结合(详细教程+源码)

1.研究背景与意义 随着科技的不断发展&#xff0c;计算机视觉技术在各个领域中得到了广泛的应用。其中&#xff0c;卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;作为一种强大的深度学习模型&#xff0c;已经在图像识别、目标检测、人脸识…

鸿蒙原生应用/元服务开发-AGC分发如何编译打包应用

软件包规范 在正式打包应用前&#xff0c;请确保已了解HarmonyOS应用软件包规范。 操作步骤 1.打开DevEco Studio&#xff0c;菜单选择“Build > Build Hap(s)/APP(s) > Build APP(s)”。 2.等待编译构建。编译完成后&#xff0c;将在工程目录“build > outputs >…

vr编辑器可以解决教育教学中的哪些问题

VR编辑器是一种基于虚拟现实技术的教育内容编辑器&#xff0c;可以帮助教师快速创建出高质量的虚拟现实教学内容。 比如在畜牧教学类&#xff0c;通过这个软件&#xff0c;教师可以将真实的动物场景、行为和特征模拟到虚拟现实环境中&#xff0c;让学生在沉浸式的体验中学习动物…

D-Wave推出新开源及解决无线信道解码新方案!

​&#xff08;图片来源&#xff1a;网络&#xff09; 加拿大量子计算机公司D-Wave&#xff08;纽约证券交易所股票代码&#xff1a;QBTS&#xff09;是量子计算系统、软件和服务领域的佼佼者&#xff0c;也是全球首家商业量子计算机供应商。 近期&#xff0c;该公司发布了一…

LangChain: 类似 Flask/FastAPI 之于 Django,LangServe 就是「LangChain 自己的 FastAPI」

原文&#xff1a;LangChain: 类似 Flask/FastAPI 之于 Django&#xff0c;LangServe 就是「LangChain 自己的 FastAPI」 - 知乎 说明&#xff1a;LangServe代替 langchainserver 成为新的langchain 部署工具 官网资料&#xff1a;&#x1f99c;️&#x1f3d3; LangServe | &…

【SpringBoot】ThreadLocal 的详解

一、ThreadLocal 简介 ThreadLocal 叫做线程变量&#xff0c;意思是 ThreadLocal 中填充的变量属于当前线程&#xff0c;该变量对其他线程而言是隔离的&#xff0c;也就是说该变量是当前线程独有的变量。ThreadLocal 为变量在每个线程中都创建了一个副本&#xff0c;那么每个线…

企业如何选择一款高效的ETL工具

企业如何选择一款高效的ETL工具? 在企业发展至一定规模后&#xff0c;构建数据仓库&#xff08;Data Warehouse&#xff09;和商业智能&#xff08;BI&#xff09;系统成为重要举措。在这个过程中&#xff0c;选择一款易于使用且功能强大的ETL平台至关重要&#xff0c;因为数…

Android:Google三方库之Firebase集成详细步骤(一)

前提条件 安装最新版本的 Android Studio&#xff0c;或更新为最新版本。使用您的 Google 账号登录 Firebase请注意&#xff0c;依赖于 Google Play 服务的 Firebase SDK 要求设备或模拟器上必须安装 Google Play 服务 将Firebase添加到应用&#xff1a; 方式&#xff1a;使用…

智慧工地综合管理平台-环境监测子系统概要设计说明书

需求说明 原始背景 由于城市建设和工业化进程的加速,工地施工过程中的部分环节由于监管不到位,导致工地扬尘污染问题日益严重,对人类健康和环境质量造成了不可忽视的影响。为了解决这一问题,政府部门和相关企业逐渐意识到了建立工地扬尘监测系统的必要性和紧迫性,因此,环…

运行代码时不同软件的参数写法

目录 pycharm终端 pycharm 如下图所示&#xff0c;不同参数间不需要什么间隔什么东西 终端 如下图所示&#xff0c;不同参数间需要用一个符号来间隔

npm ERR!问题解决

问题一 解决办法 两个文件夹【node_global】和【node_cache】 修改文件属性 问题二 解决办法 安装淘宝镜像 npm config set registry https://registry.npm.taobao.org 查看是否成功&#xff1a; npm config get registry 是淘宝的就ok