六边形架构

前言

注: 当我在学习DDD时,看到其中的六边架构,在初步了解其架构思想之后,就深深地被吸引了,因为它可以解决诸多我在项目中遇到的问题。

这里将着重介绍六边形架构的思想,以及其解决的问题,并不与其它架构做深入的对比。

六边形架构 又被称之为ports&adpers(我认为这个名称更合适),是 Cockburn在2005年提出的,目的是为了解决业务逻辑与输入输出的解耦。

架构思想

想像一下电脑如何与周边设备如何交互的:

周边设备有耳机、键盘、外接显示器、耳机等,它们通过电脑的USB、HDMI等端口进行连接;但有时刚买来一个新的设备(比如打印机),想通过USB与电脑连接,但你插上时,电脑却提示你无法识别,需要安装驱动,你按照说明,安装好驱动就可以使用了。而且比较神奇的是,我有两个鼠标,一个是ps/2接口,一个是USB接口,但插上去都可以用, 这是因为系统中安装了两种接口类型的驱动(适配器)。

通过上面的描述,我们知道,电脑与周边设备是通过端口与驱动(适配器)交互的,且只需要有相应的驱动,端口可以和不同的设备进行交互。

我们在设计架构和编码过程中经常犯一个错误,将业务逻辑与外部实体间的交互纠缠在一起。比如,在分层架构中,对数据库的访问和外部接口的访问通常放在gateway中,而由于分层构架,只做了业务的职现划分,并未做层次的解耦,造成对于外部的访问成了业务逻辑的内核;同样,对于对外提供的接口,封装在controller中,也是同样的道理。(当然,这里并不是说分层架构不好,只是处理问题的角度不同)。

六边形架构关注的是“外部”和“内部”的差别,内部业务逻辑(Application)与外设(APP,WEB,数据库等)完全隔离,仅通过Adapter 进行交互。

那Adapter起什么作用呢?它负责将与外设交互的数据(包括命令、query)转化为Application可以理解的信息(业务module),并通过内部系统提供的接口进行业务逻辑的处理。

说了那么多adpter,那port该如何界定其职责呢? 我们知道,电脑上端口定义了设备的通信协议,只要是相同的端口,无论是什么设备必须遵循这个协议,只是其通信的内容可能有所不同。对于软件系统来讲,port上端口协议的体现就是api,即业务系统对外暴露的接口,一个端口可以有多个适配器。比如一个系统提供产口的信息的展示,这时候该信息可能需要在app,web或者作为远程服务对外提供产品信息,这时候由Application是提供一个query 接口,并返回一个Product对象,至于要将其转换成app,web或者远程服务json格式,则由adapter来完成。

为什么它叫六边形架构呢?六边形的一个边就代表一个端口,但并不代表一个六边型架构就必须有6个端口,其实这和六个边没有任何关系,作者只是为了方便表达自己的思想,将架构画成了六边形,也方便使用者能够在业务架构时,更方便的设计。

这里还是提醒一下,虽然六边形强调内部和外部的区别,但并不代表我们不关注外部接口的主被动(对外提供服务,还是调用外部服务),但我们可以在实现端口和adapters 时,通过技术来屏蔽这种差异,但却不适合,也没必要使用一个完全相同的端口来屏蔽这种差异。所以一般的六边形架构架构会在左右两端各有端口,左边代表对外提供服务,右边代表调用外部服务。

通过上面的介绍,相信你已经了解了六边形的设计思想。那它这种业务逻辑和外部系统的分离,还给我们带来什么好处呢?

如上图所示,应用外对提供了两个端口,用户侧API和数据侧API。用户侧API,通过四个适配器为app,http,GUI,ie提供服务;数据侧通过两个适配器(DB和mock)为应用提供适配服务。大家看到这里,可能会有些吃惊,怎么还有mock?

是的,只需要实现data-side端口的的服务都可以为Application提供数据,对系统来说并不会感知到服务的差异,也就是说mock和db 可以提供无差异的服务。说到这里你就明白了,再也不用将测试用例嵌入到业务逻辑中了,只要实现相应的adapter就可以了,再也不用因为业务代码的变动而更改测试用例。为集成化测试提供了很大的方便。

稍后我会补充一个项目案例!!!!

http://alistair.cockburn.us/Hexagonal+architecture

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
六边形架构,也称为端口适配器架构,是一种软件架构模式,主要用于分离应用程序的业务逻辑和外部依赖。其目录结构如下: ``` app ├── adapters │ ├── inbound # 应用程序的入站适配器 │ │ ├── controllers # 控制器层,处理HTTP请求或其他协议的请求 │ │ ├── gateways # 网关层,处理与外部系统的通信 │ │ ├── presenters # 表示层,负责将业务逻辑的结果转换为适合显示的格式 │ │ └── usecases # 用例层,提供可重用的用例操作 │ └── outbound # 应用程序的出站适配器 │ ├── database # 数据库层,处理与数据库的交互 │ └── messaging # 消息队列层,处理与消息队列的交互 ├── config # 应用程序的配置 ├── domain # 应用程序的业务逻辑 │ ├── entities # 实体层,定义应用程序中的核心概念 │ ├── repositories # 仓储层,定义实体的操作接口 │ └── services # 服务层,提供应用程序的核心业务逻辑 └── main.go # 应用程序的入口文件 ``` 其中,`adapters`目录包含了应用程序的入站和出站适配器,用于处理来自外部系统的请求和与外部系统的通信。`inbound`目录包含了控制器、网关、表示和用例层,负责接收和处理来自外部系统的请求,并将其转换为业务逻辑操作。`outbound`目录包含了数据库和消息队列层,负责与这些外部系统的交互。`config`目录包含了应用程序的配置文件。`domain`目录包含了应用程序的业务逻辑,包括实体、仓储和服务层。`main.go`文件是应用程序的入口文件,用于启动应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值