极客视点
极客时间编辑部
极客时间编辑部
113241 人已学习
免费领取
课程目录
已完结/共 3766 讲
2020年09月 (90讲)
时长 05:33
2020年08月 (93讲)
2020年07月 (93讲)
时长 05:51
2020年06月 (90讲)
2020年05月 (93讲)
2020年04月 (90讲)
2020年03月 (92讲)
时长 04:14
2020年02月 (87讲)
2020年01月 (91讲)
时长 00:00
2019年12月 (93讲)
2019年11月 (89讲)
2019年10月 (92讲)
2019年09月 (90讲)
时长 00:00
2019年08月 (91讲)
2019年07月 (92讲)
时长 03:45
2019年06月 (90讲)
2019年05月 (99讲)
2019年04月 (114讲)
2019年03月 (122讲)
2019年02月 (102讲)
2019年01月 (104讲)
2018年12月 (98讲)
2018年11月 (105讲)
时长 01:23
2018年10月 (123讲)
时长 02:06
2018年09月 (119讲)
2018年08月 (123讲)
2018年07月 (124讲)
2018年06月 (119讲)
时长 02:11
2018年05月 (124讲)
时长 03:16
2018年04月 (120讲)
2018年03月 (124讲)
2018年02月 (112讲)
2018年01月 (124讲)
时长 02:30
时长 02:34
2017年12月 (124讲)
时长 03:09
2017年11月 (120讲)
2017年10月 (86讲)
时长 03:18
时长 03:31
时长 04:25
极客视点
15
15
1.0x
00:00/04:21
登录|注册

如何基于DDD设计并实现模块化单体应用?

讲述:初明明大小:3.98M时长:04:21
最近,华沙 ITSG Global 的系统架构师卡米尔·格兹别克(Kamil Grzybek)在 GitHub 发布了一个项目,给出了使用 DDD(领域驱动设计,Domain-Driven Design)方法设计并实现一个单体(monolith)应用的详细介绍。该项目的目标,就是展示如何以模块化方式设计并实现一个单体应用。此外,格兹别克还基于他在应用开发实践的收获,给开发者提出一些有用的架构建议和设计模式。
格兹别克指出,该项目的目标并非是要创建一个极简应用,或是一个验证原型(PoC,proof of concept),而是给出一种适用于生产环境的完整实现。该项目的动机,来自于格兹别克对一些类似的但并未取得成功的项目的审视。在他看来,大多数示例应用过于简单,或是不够完整。他一直认为,这些应用至少在某些部分上存在着设计和实现上的问题,或是存在着相关文档缺失的问题。
格兹别克强调指出,他的实现只是解决类似业务问题的许多方法之一。系统的软件架构需要考虑多种因素,例如功能要求、质量属性和技术约束等,另一方面也会受开发人员的经验、技术约束、时间和预算等因素的影响,所有这些因素都会影响解决方案。
该应用针对的是为大多数开发人员所认可的会议组(meeting group)领域。应用实现中考虑了额外的复杂性,因此相比基于 CRUD 的常规应用更具意义。格兹别克将主领域进一步划分为四个子域,即会议、支付、管理,以及用户访问。
为给出领域所需的功能,格兹别克采用了一种称为“事件风暴”( Event Storming )的方法在主领域的各子域中发现行为和事件。
从更高层次上看,该架构中定义了一个 API 层、包含存储的四个模块,分别对应于所发现的四个子域,还包含一个用于通信的公共事件总线(EventBus)。
模块也相应地划分为四个子模块,并分别实现为独立的二进制文件,分别为:处理所有请求的 Application、实现领域逻辑的 Domain、实现基础架构代码的 Infrastructure,以及在 EventBus 上发布事件并且是模块间唯一共享组件的 IntegrationEvents。格兹别克使用了 Decorator 模式,实现添加工作单元( Unit of Work )和日志等交叉关注点(cross-cutting)。
为分离应用内部的命令和查询,格兹别克使用并实现了 CQRS 的一种变体。该 CQRS 变体针对命令所涉及的同一数据库表,在查询中使用了原始 SQL 和视图。虽然 CQRS 还具体其他变体,但格兹别克力图避免使应用过于复杂化。
模块间的集成是基于异步事件传输的。事件传输使用了“发件箱模式”/“收件箱模式”( outbox and inbox pattern ),以及基于内存中的 EventBus 代理。为存储要发布的事件,发件箱模式在数据存储中添加了独立的表。事件的添加,实现中通过执行任务的命令,以及等同于命令的事务。此后,这些事件通过单独的流程,转发到另一个模块的收件箱中。在该项目中,事件传输是通过各模块中的后台 Worker 实现的。该实现提供了多次交付和处理。
最后,格兹别克强调该项目仍在开发中,欢迎贡献者的加入。项目是使用 C# 编写的.NET Core 应用,使用了像 Autofac (用于 IoC )、 Dapper (一种用于读取模型的 MicroORM )之类的类库。项目中还包括基于 Arrang-Act-Assert 模式的测试,使用 NUnit 实现。
此外,格兹别克在与 InfoQ 的访谈中表示,与微服务体系架构相比,模块化单体应用的主要差别之处在于部署方法和模块间通信。
在微服务架构中,每个模块都以独立的进程运行。模块间的通信必须使用网络实现,并且通常通过同步服务 API 调用(即 RPC,远程过程调用),或是使用代理(即消息传递)实现。微服务架构是一种分布式系统,具有分布式的所有优点和缺点。
对于模块化单体应用,则无需考虑分布式系统。所有模块均以同一进程运行,无需使用网络即可相互通信。各模块可以通过方法调用直接同步引用内存中对象,或是异步地使用运行于同一进程中的某个中介者(Mediator)。
以上就是就是今天的内容,希望对你有所帮助。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结
该免费文章来自《极客视点》,如需阅读全部文章,
请先领取课程
免费领取
登录 后留言

精选留言

由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。
收起评论
显示
设置
留言
收藏
99+
沉浸
阅读
分享
手机端
快捷键
回顶部