目录

  • 一、引言
  • 二、EIC(Entity-Interface-Control) & EBI(Entity-Boundary-Interactor)
  • 三、端口和适配器架构Ports & Adapters Architecture(又称六边形架构Hexagonal Architecture)
  • 四、洋葱架构Onion Architecture
  • 五、整洁架构Clean Architecture
  • 六、清晰架构Explicit Architecture
  • 七、汇总
  • 八、后续...

一、引言

最近在学习DDD应用架构设计时,接触到了不同的应用架构设计概念,如六边形架构、洋葱架构、整洁架构、清晰架构…,起初是一头雾水,在不断学习过程中也算对此有了些理解,故在本文中对这些架构进行了简单的介绍和总结。

这些架构随时间的演进可参见下图:

#mermaid-svg-hMJaAtBOjJALLpdT {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-hMJaAtBOjJALLpdT .error-icon{fill:#552222;}#mermaid-svg-hMJaAtBOjJALLpdT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hMJaAtBOjJALLpdT .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-hMJaAtBOjJALLpdT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hMJaAtBOjJALLpdT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hMJaAtBOjJALLpdT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hMJaAtBOjJALLpdT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hMJaAtBOjJALLpdT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hMJaAtBOjJALLpdT .marker.cross{stroke:#333333;}#mermaid-svg-hMJaAtBOjJALLpdT svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hMJaAtBOjJALLpdT .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-hMJaAtBOjJALLpdT .cluster-label text{fill:#333;}#mermaid-svg-hMJaAtBOjJALLpdT .cluster-label span{color:#333;}#mermaid-svg-hMJaAtBOjJALLpdT .label text,#mermaid-svg-hMJaAtBOjJALLpdT span{fill:#333;color:#333;}#mermaid-svg-hMJaAtBOjJALLpdT .node rect,#mermaid-svg-hMJaAtBOjJALLpdT .node circle,#mermaid-svg-hMJaAtBOjJALLpdT .node ellipse,#mermaid-svg-hMJaAtBOjJALLpdT .node polygon,#mermaid-svg-hMJaAtBOjJALLpdT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hMJaAtBOjJALLpdT .node .label{text-align:center;}#mermaid-svg-hMJaAtBOjJALLpdT .node.clickable{cursor:pointer;}#mermaid-svg-hMJaAtBOjJALLpdT .arrowheadPath{fill:#333333;}#mermaid-svg-hMJaAtBOjJALLpdT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hMJaAtBOjJALLpdT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hMJaAtBOjJALLpdT .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-hMJaAtBOjJALLpdT .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-hMJaAtBOjJALLpdT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hMJaAtBOjJALLpdT .cluster text{fill:#333;}#mermaid-svg-hMJaAtBOjJALLpdT .cluster span{color:#333;}#mermaid-svg-hMJaAtBOjJALLpdT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hMJaAtBOjJALLpdT :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

名词替换
提出端口、适配器概念
将应用分为内层核心业务逻辑、外层适配器实现
内层添加DDD分层
整合六边形、洋葱等架构
整合上述全部架构
更清晰、具体
EIC
Entity-Interface-Control)
1992 Ivar Jacobson
EBI
Entity-Boundary-Interacter
Robert C. Martin
Clean Architecture
端口和适配器架构(六边形架构)
Ports & Adapters Artchitechture
Hexagonal Architecture
2005 Alistair Cockburn
整洁架构
Clean Architechure
2012 Robert C. Martin (AKA Uncle Bob)
洋葱架构
Onion Architecture
2008 Jeffrey Palermo
清晰架构
Explicit Architecture
2017 Herberto Graca

接下来依次介绍各架构。

二、EIC(Entity-Interface-Control) & EBI(Entity-Boundary-Interactor)

1992年由Ivar Jacobson提出EIC(Entity-Interface-Control) 架构,
之后Robert C. Martin在一次关于整洁架构Clean Architecture的演讲中将其调整为EBI(Entity-Boundary-Interactor),即:

  • Entity => Entity: 维持不变
  • Interface => Boundary: 避免和编程语言中的interface相混淆
  • Control => Interactor: 避免和MVC Controller相混淆

注: 参考上图EBI架构,图片中的矩形边数或边界数量为4,
若将其修改为6边型,即可演进为2005年(13年后)提出的六边形架构(见下文),
即可以将其视为六边形架构(端口、适配器架构)思想的前身。

EBI对象类型说明如下:

  • Entity: 实体对象,包含数据、行为(避免贫血模型anaemic entities)
  • Boundary(Interface): 系统与外界交互的边界,即对应bounday object,如controller实现(主动)、持久化实现(被动)、消息通知(被动)等。
  • Interactor(Control): 所有不适合放在Entity和Boundary的行为都需要放在Interactor对象中,等价于DDD中的:
    • Application Services(who orchestrate(编排) use cases) - DDD架构中的应用服务层
    • Domain Services (who contain Domain behaviour but are not entities) - DDD架构中的领域服务层

类比MVC(Model View Controller)模式,

  • 模型层Model即表示整个后端back-end,包括services、entities等
  • 表现层Presentation即包含View层、Controller层
  • View层、Controller层即为Boundary,
  • Entity即为实体数据及其关联的行为操作(充血模型)
  • Interactor(Application Services, Domain Services)即为表现层(View、Controller)和Entity的连接,
  • 将MVC和EBI模式组合起来类似:View-Controller-Interactor-Entity

三、端口和适配器架构Ports & Adapters Architecture(又称六边形架构Hexagonal Architecture)

2005年,Alistair Cockburn提出了端口和适配器架构Ports & Adapters Architecture(又称六边形架构Hexagonal Architecture)。

端口和适配器架构中的相关概念:

  • 工具Tools: 应用application使用的工具Tools(WebSerevr, Cli, DB, SearchEngine, MQ)

  • 端口Port: 在application core层定义的工具交互规范(即定义 工具Tools如何使用application core的规范 或 工具Tools如何被application core使用的规范),对应编程语言的interface定义,且端口定义应该符合应用层逻辑(不可简单模仿或者直接使用底层工具的API)

  • 适配器Adapter: 连接工具Tools(WebSerevr, Cli, DB, SearchEngine, MQ)和应用核心application core的代码单元

    • 适配器依赖port(调用port 或 实现port)和工具,但是application core仅依赖port。
  • 主动适配器(Primary/Driving Adapters ) - 主动调用应用核心Application Core,触发应用执行某项活动

    • 主动适配器 -> 依赖端口 -> 注入端口实现
    • 例如主动适配器Controller -> 依赖端口ServiceInterface -> 注入端口实现ServiceImpl
  • 被动适配器(Secondary/Driven Adapters) - 被应用核心Application Core调用来执行动作,实现应用定义的端口

    • 端口 -->被动适配器实现端口逻辑-> 包装系统外部工具,
    • 例如端口RespositoryInterface -> 被动适配器Mysql实现MysqlRepositoryImpl -> 调用Mysql数据库

几边形不重要,可以N多边,重点是Port & Adapter思想,关于端口和适配器架构的优势:

  • 核心业务在最中心(最重要),
  • 核心业务依赖Port,Adapter依赖Port(主动) 或 Adapter为Port的具体实现(被动),
  • 核心业务逻辑与实现细节(技术框架、底层存储、工具、传输通信机制等)相隔离,
  • 保持核心业务逻辑的可重用性,
  • 可通过(注入)不同Adapter实现来切换技术实现,避免技术框架、工具、供应商锁定,
  • 且基于mock Port的形式更易于测试。

四、洋葱架构Onion Architecture

洋葱架构(Onion Architecture) 在2008年由Jeffrey Palermo提出。


洋葱架构 构建在Port & Adapter架构(又称六边形架构)之上,在Port & Adapter架构中仅提到2层:
1)外层 - 表示传输(通信)机制和基础设施infrastructure
2)内层 - 业务逻辑

洋葱架构在DDD的基础上,将内层(业务逻辑层,Business Logic)进一步划分,最终为:

  • Adapters,即六边形架构中的适配器Adapter层

    • User Interface、Infrastructure、Tests
  • Application Core,应用核心层,也即原来的六边形架构中心的Business Logic层
    • Application Services - 应用服务册层
    • Domain Services - 领域服务层
    • Domain Model - 领域模型层

明确了依赖方向

  • 外层依赖内层
  • 内层不知道外层
  • 且在不破坏依赖方向的前提下,外层亦可以直接调用任一内层(不一定是相邻接的2层),参考CQRS中Query实现(Application Services直接调用DAO)

五、整洁架构Clean Architecture

2012年Robert C. Martin (又名Uncle Bob) 提出了整洁架构Clean Architecture,整洁架构将EBI、六边形架构Hexagonal、洋葱架构Onoin等整合成一个可以实际落地的架构。

与洋葱架构相比,整洁架构调整如下:

  • Application Services调整为Use Cases
  • Domain Services, Domain Model调整为Entities

整洁架构并没有带来突破性的概念或模式,但是:

  • 它发掘了某种程度上被遗忘了的概念、规则和模式;
  • 它澄清了一些实用且重要的概念、规则和模式;
  • 它告诉我们如何把所有的概念、规则和模式整合起来,形成一种构建复杂应用并保持可维护性的标准套路

六、清晰架构Explicit Architecture

2017年Herberto Graca在其软件架构编年史系列文章中提出清晰架构Explicit Architecture,即将DDD, Hexagonal, Onion, Clean, CQRS等进行融合后的架构。

  • 最中心的红色多边形Application Core即表示业务逻辑实现,即应用核心

    • 红色多边形的边界即表示端口Port,即应用核心的入口/出口定义
    • Application Layer - 应用层,包括:
      • Application Services,业务用例的编排服务即及其interface定义,应用服务的作用通常如下:

        • 使用 Repostitory 查找一个或多个实体;
        • 让这些实体执行一些领域逻辑;
        • 再次使用 Repostitory 让这些实体持久化,有效地保存数据变化;
        • 触发应用事件(如发送邮件、调用第三方API、发送MQ消息等)。
      • CQRS命令/查询处理器
      • Event Listener事件监听器
      • Port端口定义,如ORM 接口Repostitory、搜索引擎接口、消息接口等等
    • Domain Layer - 领域层,这一层含了数据和操作数据的逻辑,它们只和领域本身有关,独立于调用这些逻辑的业务过程。它们完全独立,对应用层完全无感知。
      • Domain Services - 领域服务,封装涉及多实体(相同或不同实体类型)的领域逻辑,且领域服务间可以相互调用。
      • Domain Models - 领域模型,在架构的正中心,完全不依赖外部任何层次的领域模型。它包含了那些表示领域中某个概念的业务对象,如实体、值对象、枚举以及其它领域模型种用到的任何对象(如领域事件Domain Events,简单理解为MQ消息)。
  • 红色多边形的外侧左半圆部分即为主/主动适配器(用户界面User Interface实现)
    • 如Spring MVC中的Controller实现
    • Command Query Bus 命令查询总线
  • 红色多边形的外侧右半圆部分即次/被动适配器(基础设置Infrastructure实现)
    • 如数据持久化实现Mysql、短信通知实现、MQ通知、搜索引擎ES实现等
    • Event Bus 事件总线
  • 依赖方向由外到内,且内层不知道外层(参见之前洋葱架构)

采用按组件分包Package By Component,即整合传统按层分包Package By Layer和按特性分包Package By Feature,组件Component可以理解为专属于特定一个领域内的业务逻辑服务和数据访问逻辑的组合,也可以理解为特定领域,如账单、用户、评论或帐号等。

A “component” in this sense is a combination of the business and data access logic related to a specific thing (e.g. domain concept, bounded context, etc).

在清晰架构中可以理解为:

  • 先按照层次进行分包

    • 表现层Presentation
    • 业务核心层Application Core
    • 基础设施层Infrastructure)
  • 之后每一层次再按照特性分包

正如Herberto Graca在DDD, Hexagonal, Onion, Clean, CQRS, … How I put it all together中写到:

清晰架构只是一份指南!
应用才是疆域,现实情况和具体用例才是运用这些知识的地方,它们才能勾勒出实际架构的轮廓!
我们需要理解所有这些模式,
但我们还时常需要思考和理解我们的应用需要什么,我们应该在追求解耦和内聚的道路上走多远。
这个决定可能受到许多因素的影响,
包括项目的功能需求,也包括构建应用的时间期限,应用寿命,开发团队的经验等等因素。


附国内大神翻译的清晰架构中文版:

关于传统分层、六边形、洋葱、整洁、清晰架构的演进可参见下图:

七、汇总

综合以上架构,给出我认为合理的、可以落地的架构如下图(后续会根据实际的使用体验进行完善):

八、后续…

  • 清晰架构中跨组件通信
  • CQRS处理
  • 共享内核等
  • Event Driven
  • 限界上线文、上下文映射

参考:

EBI:
https://herbertograca.com/2017/08/24/ebi-architecture/

端口和适配器架构:
11.端口和适配器架构(译) - https://www.jianshu.com/p/f39f4537857e
https://herbertograca.com/2017/09/14/ports-adapters-architecture/

洋葱架构:
https://herbertograca.com/2017/09/21/onion-architecture/
https://jeffreypalermo.com/2008/07/the-onion-architecture-part-1/

整洁架构:
https://herbertograca.com/2017/09/28/clean-architecture-standing-on-the-shoulders-of-giants/
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

清晰架构:
https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/
17.清晰架构(01): 融合 DDD、洋葱架构、整洁架构、CQRS…(译) - https://www.jianshu.com/p/d3e8b9ac097b

DDD:
https://herbertograca.com/2017/09/07/domain-driven-design/

DDD中常提到的应用架构总结(六边形、洋葱、整洁、清晰)相关推荐

  1. 物联网中常提到的M2M究竟是什么?

    随着物联网逐渐深入现代生活,很多通信技术也涌现出来.今天,小编就和大家分享下M2M技术的相关知识. M2M技术简述 M2M(MachinetoMachine),是通过移动通讯对设备进行有效控制,从而将 ...

  2. 开发中常提到的脚手架是指的什么?

    以下是在网上查到的对脚手架的各种解释: 1.脚手架是指通过输入简单指令帮助你快速搭建好一个基本环境的工具,就比如gulp是任务自动构建工具,gulp-cli则是以命令行的形式安装和操作gulp的工具 ...

  3. 浅谈面试中常提到的乐观锁与悲观锁

    首先来看一下什么是锁? 在并发环境下,会出现多个线程对同一个资源进行争抢的情况,假设A线程对资源正在进行修改,此时B线程此时又对资源进行了修改,这就可能会导致数据不一致的问题.为了解决这个问题,很多编 ...

  4. 目标检测中常提到的IoU和mAP究竟是什么?

    看完这篇就懂了. IoU intersect over union,中文:交并比.指目标预测框和真实框的交集和并集的比例. mAP mean average precision.是指每个类别的平均查准 ...

  5. 什么是.NET开发中常提到的CLR

    CLR是common language runtime的简写,即公共语言运行时,它是微软向ECMA提交的CLI规范的一个具体实现.CLI即common language infrastructure, ...

  6. DDD 中的CQRS(命令查询职责分离)架构模型有哪些?

    更多内容关注微信公众号:fullstack888 命令/查询分离(CQS) 1988 年,Bertrand Meyer 在面向对象的软件设计一书中设计了 CQS 原则.简单来说,这个原则是说程序应当要 ...

  7. WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例

    最近出于工作需要,了解了一下微服务架构(Microservice Architecture,MSA).我经过两周业余时间的努力,凭着自己对微服务架构的理解,从无到有,基于.NET打造了一个演示微服务架 ...

  8. 深入理解DDD中的聚合

    本文来说下领域驱动设计中的聚合 文章目录 概述 聚合解决的核心问题是什么 聚合划分的原则 生命周期一致性 问题域一致性 场景频率一致性 尽量小的聚合 实现方面的考虑 资源库.工厂面向聚合定义 代码结构 ...

  9. ddd java repository_初探领域驱动设计(2)Repository在DDD中的应用

    概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...

  10. 关于DDD中Domain的思考

    2019独角兽企业重金招聘Python工程师标准>>> 本文既不推销UML,也不推广DDD,更不涉及各种论战.-- 作者 某天又一次打开关于DDD(领域驱动设计)的PDF文档时,自己 ...

最新文章

  1. 如何在ASP.Net 中把图片存入数据库
  2. 谷歌浏览器跨域报错解决办法
  3. wprintf显示中文
  4. 同学大多数都是上的整个网站重点我的
  5. java怎样自动调用鼠标点击屏幕固定地方_python办公自动化:让PyAutoGUI来帮你干活...
  6. php界面框架luy_LazyPHP
  7. Activiti的历史记录级别
  8. 如何用gitbook写文档并存到github上
  9. 【公告】个人站点及系列文章
  10. 计算机的输入法如何使用简短描述,应用电脑(1)第一章 计算机组成与中文输入法...
  11. 【CV】ShuffleNet:通过 GroupConv 和 ChannelShuffle 实现轻量化 CNN 架构
  12. 新中大 金蝶 用友产品技术比较
  13. 燃料电池多点恒功率工作Cruise仿真模型
  14. 猫盘群晖DSM7.0三合一修复脚本
  15. 2022深圳国际自有品牌展正式启动,谱写自有品牌供应链新篇章
  16. 快速开发jdeveloper12C-bpm流程图
  17. C语言人造指针,易语言置入CE自动脚本游戏修改模块源码
  18. 一车abs线路怎么量_abs传感器怎么测量好坏
  19. ar unity 小程序_unity可以写微信小程序吗?
  20. Unity 查找子节点物体/组件 递归方法

热门文章

  1. ios特定界面强制横屏
  2. MediaRecorder MPEG4Writer
  3. 阿里云双十一服务器注册流程
  4. C# 调用outlook 发送邮件
  5. nginx反向代理与正向代理
  6. Linux性能调优,从优化思路说起
  7. Master of Typing Tutor 1.2.3 特别版 Mac 打字练习软件掌握打字
  8. Flash:动画实例--球体弹跳
  9. linux如何卸载oracle数据库实例,linux下删除oracle数据库实例
  10. Flixel横板游戏制作教程(八)—MovingPlatforms(移动平台)