领域驱动设计实现疑难解答(一):如何分包及组织工程结构
接到一项业务,我们首先下意识要解决这些问题,而为了解决业务问题,需要处理用户输入,处理业务逻辑,访问数据库,进行网络通信,向用户显示信息等。
而其中处理业务逻辑,是我们最需要关注的事情。
由于我们是领域驱动设计,而不是数据表驱动设计,所以我们优先考虑某场景下实体可能有哪些业务行为,而不是实体有哪些属性,也即根据用例流来设计软件。
如何分包以及组织工程结构?
在DDD的战略设计中,我们关注于从一个宏观的视角俯视整个软件系统,然后通过一定的原则对系统进行子域和限界上下文的划分,即通过软件所实现的业务功能进行模块化划分。
在DDD中,聚合根是主要业务逻辑的承载体,也是“内聚性”原则的典型代表,因此通常的做法便是基于聚合根进行顶层包的划分。
以常见的用户登录网站为例,涉及到的聚合根显然是用户,可分为User包。
DDD将系统分为四种不同的层:
- 用户界面(UI) 负责向用户显示信息和解释用户指令,用户不仅仅代表使用界面的人
- 应用服务(application) 定义软件要完成的任务,协调下一层领域对象的工作
- 领域模型(domain) 负责表达业务概念、业务状态信息以及业务规则
- 基础设施(infrastructure)为上面各层提供通用的技术能力,包括持久化,传递消息,绘制界面等
- 服务暴露 (service)
- 仓储实现 (persistence)
- 防腐层实现 (adapter)
上层可以调用或依赖下层,下层不能依赖上层。
1.简单分包
通常情况,目录组织如下:
├── order├── OrderApplicationService.java├── OrderController.java├── OrderPaymentProxy.java├── OrderPaymentService.java├── OrderRepository.java├── command //命令对象├── ChangeAddressDetailCommand.java├── CreateOrderCommand.java├── OrderItemCommand.java├── PayOrderCommand.java└── UpdateProductCountCommand.java├── exception├── OrderCannotBeModifiedException.java├── OrderNotFoundException.java├── PaidPriceNotSameWithOrderPriceException.java└── ProductNotInOrderException.java├── model //领域模型├── Order.java├── OrderFactory.java├── OrderId.java├── OrderIdGenerator.java├── OrderItem.java└── OrderStatus.java└── representation //展现层├── OrderItemRepresentation.java├── OrderRepresentation.java└── OrderRepresentationService.java
2.复杂分包
若聚合根复杂程度更高,比如聚合根内聚其他聚合根,则以如下方式组织目录:
├── com.example.user //顶级模块名+限界上下文├── resource //用户界面层├── RoleController.java└── UserController.java ├── application //应用层├── command //命令对象└── CreateUserCommand.java├── representation //展现层├── UserRepresentationService.java└── UserSummaryRepresentation.java└── UserApplicationService.java //应用服务├── domain //领域层└── model //领域模型├── user //分包├── UserId.java //值对象└── User.java //聚合根└── role //分包├── RoleId.java //值对象└── Role.java //聚合根└── infrastructure //基础设施层├── services //领域服务└── MD5EncryptionService.java└── persistence //持久化└── UserRepository.java //资源库
注意,上面是复杂情况下的目录组建方式,是分清子领域后的再分层,包内各概念是紧密联系高内聚的。
3.错误分包
不要直接根据分层组织来组建目录,比如这样:
├── com.example.project ├── controller //用户界面层 ├── OrderController.java├── ArticleController.java└── UserController.java ├── application //应用层├── OrderApplicationService.java ├── ArticleApplicationService.java └── UserApplicationService.java //应用服务├── domain //领域层└── model //领域模型├── user //分包├── UserId.java //值对象└── User.java //聚合根└── Order //分包├── OrderId.java //值对象└── Order.java //聚合根└── infrastructure //基础设施层├── UserRepository.java └── OrderRepository.java
直接把同一领域的概念分散到四个层次中,每个模块都要乘以4,这样关注点的确得到了集中,但是减弱了领域模型的联系,很难跟踪同一概念。
4.组合多个限界上下文的情况
当用户界面需要组合多个限界上下文时,甚至不属于自己领域的外来来源的领域对象时,分包就遇到了困难。
├── com.example.project ├── User //用户上下文 ├── Order //订单上下文├── Article //图文上下文├── Product //产品上下文└── ProductArticle //产品图文上下文├── controller //控制器└── application //应用层
这时,可以思考这种情况是否产生了新的领域上下文?
可以另外新建组合包,同时只包含应用层,不包含领域层。
若认为产生了新的领域,则添加领域层。
目录:
领域驱动设计实现疑难解答(二):如何建模
领域驱动设计实现疑难解答(三):如何处理关联
领域驱动设计实现疑难解答(四):如何渲染数据
领域驱动设计实现疑难解答(五):如何发布领域事件
领域驱动设计实现疑难解答(一):如何分包及组织工程结构相关推荐
- DDD领域驱动设计落地实践系列:战略设计和战术设计
引言 通过前面的文章介绍,相信大家对于什么是DDD有了初步的了解,知道它是一种微服务的架构设计方法论,为我们解决如何建立领域模型,如何实现微服务划分等提供了方向和指导.但是对于如何具体落地使用DDD, ...
- DDD 领域驱动设计落地实践系列:战略设计和战术设计
引言 通过前面的文章介绍,相信大家对于什么是 DDD 有了初步的了解,知道它是一种微服务的架构设计方法论,为我们解决如何建立领域模型,如何实现微服务划分等问题提供了方向和指导.但是对于如何具体落地使用 ...
- 【你问我答】DDD(领域驱动设计)实践中遇到问题了?尽管问,我们负责解答!...
点击上方"蓝字"可以订阅哦 [你问我答]是由美团点评技术团队推出的线上问答服务,你在工作学习中遇到的各种技术问题,都可以通过我们微信公众号发问,我们6000+工程师会义务为你解答, ...
- 领域驱动设计,为何死灰复燃?
作者简介 张逸,曾先后就职于中兴通讯.惠普 GDCC.中软国际.ThoughtWorks 等大型中外企业,任职角色为高级软件工程师.架构师.技术总监.首席咨询师. 一.领域驱动设计为何又死灰复燃焕发青 ...
- 【吐血推荐】领域驱动设计学习输出
一.Hello DDD 刚开始接触学习「DDD - 领域驱动」的时候,我被各种新颖的概念所吸引:「领域」.「领域驱动」.「子域」.「聚合」.「聚合根」.「值对象」.「通用语言」.....总之一大堆有关 ...
- 万字长文助你上手软件领域驱动设计 DDD
作者:faryrong,腾讯 CSIG 后台开发工程师 最近看了一本书<解构-领域驱动设计>,书中提出了领域驱动设计统一过程(DDDRUP),它指明了实践 DDD 的具体步骤,并很好地串联 ...
- 如何系统学习领域驱动设计?
一.领域驱动设计为何又焕发青春? 领域驱动设计(Domain Driven Design,DDD)确实已不再青春,从 Eric Evans 出版了划时代的著作<领域驱动设计>至今,已有将近 ...
- 阿里文娱技术专家战獒: 领域驱动设计详解之What, Why, How?
战獒 阿里文娱技术专家 读完需要 8 分钟 速读仅需 3 分钟 阿里妹导读:什么是领域驱动设计?传统分层架构在实际开发中存在哪些问题?业务开发人员如何设计并搭建自己的领域模型?阿里文娱技术专家战獒将为 ...
- 初始DDD(领域驱动设计)
本文来说下DDD,第一次认识DDD.后面会多写几篇文章来深入理解下什么是DDD. 文章目录 概述 什么是DDD 啥是驱动 建立领域知识(Build Domain Model) 通用语言(Ubiquit ...
最新文章
- Ubuntu中Atom编辑器显示中文乱码的处理方法
- 学java是不是必须要参加java培训班?
- 高性能mysql:创建高性能的索引
- java指导手册,Java 注解指导手册 – 终极向导
- 关于迷笛音乐节的重大通知-_-
- 【Get 以太坊技能】CentOS 7 Geth安装
- mysqldump全量恢复_删库不跑路-详解MySQL数据恢复
- ASP.NET Core 源码学习之 Options[2]:IOptions
- Hexo如何绑定个人域名
- C语言线性表之双向循环链表
- 如何批量新建文件夹并命名
- PGP加密并签名邮件 实验
- python矩阵连乘_第3章 动态规划——矩阵连乘最优计算方式查找
- 串口总线舵机之舵机命令
- 网友发帖曝最剽悍翻译 贵阳译成昂贵的太阳
- 求三角形的外接圆圆心个半径
- 解决IDEA占用C盘空间过大的问题
- 抓包工具Charles+fiddler使用方法(一)自用
- 会轻易的找到“回家”的路
- There are test failures.
热门文章
- arduino nano 的引脚输出脉冲,到底有多快?蚂蚁指挥大象,脉冲控制伺服电机走位的测试。
- opencv-python 轮廓查找 椭圆拟合 画椭圆
- 错误代码 CS0234
- 天之痕——Tacke竹桑
- Sams Teach Yourself SQL in 10 Minutes, Third Edition
- 微信小程序wx.login()、wx.getSetting、wx.getUserInfo的区别和联系?
- Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
- 德鲁克的二十条管理格言
- 注意力机制——Coordinate Attention
- PCIe(三):PCIe分层结构