DDD之六边形架构(Hexagonal Architecture)

news2024/9/24 5:24:49

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

六边形架构(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;
    }

    @PostMapping
    public ResponseEntity<Product> addProduct(@RequestBody Product product) {
        Product addedProduct = productService.addProduct(product);
        return ResponseEntity.ok(addedProduct);
    }

    @GetMapping
    public 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 {

    @Bean
    public ProductService productService(ProductServiceFeignClient productServiceFeignClient) {
        return new ProductServiceAdapter(productServiceFeignClient);
    }
}

4.5 配置文件

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

spring:
  application:
    name: product-service

product-service:
  server:
    port: 8080

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

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

5. 结语

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


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

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

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

相关文章

Ajax基础(应用场景|jquery实现Ajax|注意事项|Ajax发送json数据|Ajax携带文件数据)

文章目录 一、Ajax简介二、基于jquery实现Ajax三、使用Ajax注意的问题1.Ajax不要与form表单同时提交2.后端响应格式问题3、使用了Ajax作为请求后的注意事项 四、前后端数据传输的编码格式(content-Type)1.urlencoded2.formdata3.application/json 五、Ajax携带文件数据六、Ajax…

稳定性保障8个锦囊,建议收藏!

稳定性保障&#xff0c;是一切技术工作的出发点和落脚点&#xff0c;也是 IT 工作最核心的价值体现&#xff0c;当然也是技术人员最容易“翻车”的阴沟。8个稳定性保障锦囊&#xff0c;分享给各位技术人员择机使用。 #1 设定可量化的、业务可理解的可用性目标 没有度量就没有改…

快来瞧瞧这样制作出来的电子画册,还便于分享宣传呢!

说起电子画册制作&#xff0c;很多人都不知道从何入手。与传统纸质画册相比&#xff0c;电子画册最大的优点是便于传阅&#xff0c;通过微信、QQ等社交平台都能进行转发和分享。而且内容的排版基本上和纸质画册一致&#xff0c;不同的是&#xff0c;无论图片还是文字都可以赋予…

【数据结构算法(二)】链表总结

&#x1f308;键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 普通单向链表 双向链表 带哨兵的链表 环形链表 ⭐双向带头带环链表的实现⭐ ⭐链表基础OJ⭐ 普通单向链表 结点结构&#xff1a;只有val 和 next指针 初始时&#xff1a;head null; 双向链表 指针&…

特征工程完整指南 - 第一部分

苏米特班迪帕迪亚 一、说明 特征工程是利用领域知识从原始数据中提取特征的过程。这些功能可用于提高机器学习算法的性能。本篇叙述在特征选择过程的若干数据处理。 一般来说&#xff0c;特征工程有以下子步骤&#xff1a; 特征转换特征构建特征选择特征提取 二、特征转换的缺…

12.文档中添加Appendix

要在 LaTeX 文档中添加附录&#xff0c;您可以使用 \appendix 命令&#xff0c;它会告诉 LaTeX 后续部分是附录。以下是添加附录的步骤&#xff1a; 在文档的导言部分&#xff08;在 \begin{document} 之前&#xff09;导入 appendix 宏包。您可以使用以下命令&#xff1a; \…

Centos8部署MySQL主从复制报错问题

问题1.在部署MySQL主从复制时&#xff0c;创建用户提示ERROR 1819&#xff1a;Your password does not satisfy the current policy requirements。即为当前配置的密码&#xff0c;不符合策略要求。 问题1解决方式&#xff1a; set global validate_password.policyLOW; \\…

「Verilog学习笔记」含有无关项的序列检测

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1ns module sequence_detect(input clk,input rst_n,input a,output reg match);reg [8:0] a_tem ; always (posedge clk or negedge rst_n) begin if (~rs…

jvs-智能bi(自助式数据分析)11.21更新功能上线

jvs智能bi更新功能 新增: 1.字段设置节点新增自定义时间格式功能&#xff1b; 自定义功能允许用户根据需要自定义日期和时间字段的显示格式&#xff0c;为用户提供了更大的灵活性和便利性 2.图表时间搜索条件新增向下兼容模式&#xff1b; 时间搜索条件的向下兼容模式允许用…

万界星空科技QMS质量管理系统介绍

QMS&#xff08;Quality Management System&#xff09;质量管理系统是五大基础系统之一&#xff0c;在工业企业中被广泛的应用&#xff0c;在质量策划、生产过程质量监督、体系审核和文档管理等业务上发挥着不可替代的作用。 一般制造业工厂现状&#xff1a;质量成本高&#x…

运动耳机哪个牌子好?盘点最值得入手的五款运动耳机

现在&#xff0c;不入耳的运动耳机成了许多运动爱好者的首选&#xff0c;我也不例外&#xff0c;不得不说骨传导耳机跟运动真的很搭&#xff0c;不仅佩戴稳固不掉落&#xff0c;而且防水好&#xff0c;可以说是最值得入手的运动耳机&#xff0c;为了避免大家在选购运动耳机的时…

超级会员卡积分收银系统源码 会员卡+积分商城+收银功能+多门店系统 附带完整的搭建教程

线上线下的融合已经成为趋势。在这个过程中&#xff0c;会员卡积分收银系统成为了许多企业不可或缺的一部分。该系统以超级会员卡为基础&#xff0c;结合积分商城、收银功能以及多门店系统&#xff0c;为企业提供了一站式的解决方案&#xff0c;帮助企业实现线上线下会员一体化…

CAS方式实现单点登录SSO

1. CAS介绍 CAS&#xff08;Central Authentication Service&#xff09;中心认证服务 下面这张图来自官网&#xff0c;清晰简单的介绍了CAS的继续交互过程 2. CAS具体实现 首先需要分别搭建CAS-server和CAS-client服务&#xff0c; 这两个服务分别在2台机器上&#xff0c;…

2023年国自然植物科学相关面上项目信息公布(小麦、大麦、棉花、大豆、玉米)

2024年申报国自然项目基金撰写及技巧http://mp.weixin.qq.com/s?__bizMzA4NTAwMTY1NA&mid2247575761&idx1&sn32dbacd3393f3b76a1e0668e4b8b3c89&chksm9fdd7c08a8aaf51ec31d4790067bb57751a09947eeb7e728b8c008d26b89adba37e0cab32a62&scene21#wechat_redi…

梨花教育,精心的声音可提升罪案剧的吸引力和体验

在为罪案剧录制配音时&#xff0c;配音员应致力于营造剧集所需的紧绚和不确定性&#xff0c;同时准确地传达角色的心理活动和情绪纠葛。罪案剧往往围绕着刑侦探索、法律较量、道德抉择等主题展开&#xff0c;因此配音需要与这些情境相适应。以下是进行罪案剧配音时的几点建议&a…

Vue 2使用element ui 表格不显示

直接修改package.json文件 把这两个依赖修改成对应的 删除node_modules 重新安装依赖 重启

集成电路工厂用什么ERP?哪家的集成电路ERP比较好

集成电路通常对制造工艺、生产设备、品质检验等方面有较高的要求&#xff0c;而随着智能技术和自动化技术的发展成熟&#xff0c;如今集成电路行业逐渐迈入数字化和智能化阶段&#xff0c;而至这个时代背景当中&#xff0c;很多集成电路工厂借助ERP实现信息化转型升级。 时至今…

汽车托运汽车会产生公里数吗?

汽车托运&#xff0c;顾名思义就是把汽车放在板车上进行托运&#xff0c;既然是被托运&#xff0c;那为什么还会产生公里数呢?是被司机私用了吗?还是被当成租赁工具租借出去了呢? 其实不然&#xff0c;回到托运流程里&#xff0c;特别是大板车&#xff0c;我们的线路有很多需…

008 OpenCV matchTemplate 模板匹配

目录 一、环境 二、模板匹配算法原理 三、代码演示 一、环境 本文使用环境为&#xff1a; Windows10Python 3.9.17opencv-python 4.8.0.74 二、模板匹配算法原理 cv.matchTemplate是OpenCV库中的一个函数&#xff0c;用于在图像中查找与模板匹配的特征。它的主要应用场景…

为何内存不够用?微服务改造启动多个Spring Boot的陷阱与解决方案

在生产环境中我们会遇到一些问题&#xff0c;此文主要记录并复盘一下当时项目中的实际问题及解决过程。 背景简述 最初系统上线后都比较正常风平浪静的。在系统运行了一段时间后&#xff0c;业务量上升后&#xff0c;生产上发现java应用内存占用过高&#xff0c;服务器总共64…