DDD领域驱动设计-项目包结构说明-Ⅳ

1. 展示层
* userinterfaces: 展示层,又称用户接口层
* 用户接口层为外部用户访问底层系统提供交互界面和数据表示。
* 用户接口层在底层系统之上封装了一层可访问外壳,为特定类型的外部用户(人或计算机程序)访问底层系统提供访问入口,并将底层系统的状态数据以该类型客户需要的形式呈现给它们。
*
* 用户接口层有两个任务:
* 从用户处接收命令操作,改变底层系统状态;
* 从用户处接收查询操作,将底层系统状态以合适的形式呈现给用户。
*
* 本例用户接口层包括如下子模块:
* 命令目录(command): 对象命名为XxxCommand,指调用方明确想让系统操作的指令,其预期是对一个系统有影响,也就是写操作。通常来讲指令需要有一个明确的返回值(如同步的操作结果,或异步的指令已经被接受)。
* 查询目录(query): 对象命名为XxxQuery,指调用方明确想查询的东西,包括查询参数、过滤、分页等条件,其预期是对一个系统的数据完全不影响的,也就是只读操作。
* 事件目录(event): 对象命名为XxxEvent,指一件已经发生过的既有事实,需要系统根据这个事实作出改变或者响应的,通常事件处理都会有一定的写操作。事件处理器不会有返回值。这里需要注意一下的是,
* Application层的Event概念和Domain层的DomainEvent是类似的概念,但不一定是同一回事,这里的Event更多是外部一种通知机制而已。
* 返回数据对象目录(dto): 对象命名为XxxDto,作为ApplicationService的出参
* 控制层(Controller): 提供restful接口,供外部系统调用
*
* 规范:
* ApplicationService的接口入参只能是一个Command、Query或Event对象,CQE对象需要能代表当前方法的语意。唯一可以的例外是根据单一ID查询的情况,可以省略掉一个Query对象的创建
* CQE,Dto,都是Value Object,但是从语义上来看有比较大的差异,主要是从命名上区别出来。
* CQE:CQE对象是ApplicationService的输入,是有明确的“意图”的,所以这个对象必须保证其"正确性"。为验证部分字段的格式,必填性,可基于Spring Validation等模式做基础数据验证。
* DTO:Dto对象只是数据容器,只是为了和外部交互,所以本身不包含任何逻辑,只是贫血对象。
2. 应用层
* application 应用层
* 相对于领域层,应用层是很薄的一层,应用层定义了软件要完成的任务,要尽量简单.
* 它不包含任务业务规则或知识, 为下一层的领域对象协助任务、委托工作。这一层也很适合写一些任务处理,消息处理
* 它没有反映业务情况的状态,但它可以具有反映用户或程序的某个任务的进展状态。
*
* 对外:为展现层提供各种应用功能(service)。
* 对内:调用领域层(领域对象或领域服务)完成各种业务逻辑任务
*
* 事件(event): 对象命名为XxxEvent,跨聚合根,或部分业务处理完成后,需要通知其他模块的,本例采用 Spring event模式。本例是将领域事件放在应用层的。
* 应用服务(service): 对象命名为XxxService,应用层的服务
*
* 一个应用层通常包括以下三种服务:
*
* 业务处理类:XxxCommandService
* 业务查询类:XxxQueryService
* 业务事件类:XxxEventService
3. 领域层
* domain 领域层
* 领域层主要负责表达业务概念,业务状态信息和业务规则。是一个纯内存化的操作。
* Domain层是整个系统的核心层,几乎全部的业务逻辑会在该层实现。领域层不关注数据是如何落地存储的,领域层也不直接调用底层仓库接口保存数据。
* 领域模型层主要包含以下的内容:
*
* 实体(Entities): 对象命名为XxxE,具有唯一标识的对象,所有实体统一用E作为后缀,如PersonE
* 工厂(factory): 接口命名规则为XxxFactory,创建复杂的实体,聚合根,只做创建处理
* 值对象(vo): 对象命名为XxxV,无需唯一标识的对象,所有值对像统一同V作为后缀 ,如PersonV,实体的主键编码以Id结尾
* 领域服务(Domain Services): 接口命名规则为XxxDomainService,一些行为无法归类到实体对象或值对象上,本质是一些操作,而非事物(与本例中domain/service包下的含义不同)
* 仓储(Repository): 接口命名规则为XxxRepository,创建复杂对象,隐藏创建细节,提供查找和持久化对象的方法。本层仅编写仓库的接口。具体实现再基础层
* 聚合/聚合根(Aggregates,Aggregate Roots): 对象命名为XxxA,聚合是指一组具有内聚关系的相关对象的集合,每个聚合都有一个root和boundary,所有聚合统一用A作为后缀,如PersonA
*
4. 基础实施层
* infrastructure 基础实施层
* 向其他层提供 通用的 技术能力(比如工具类,第三方库类支持,常用基本配置,数据访问底层实现)
* 基础实施层主要包含以下的内容:
* 为应用层 传递消息(比如通知)
* 为应用层 提供持久化机制(最底层的实现)
*
* 防腐层(acl): 实体对接外部系统,实体与外部系统之间,不同领域之间,不同的参数转换,语义转换等
* 转换层(assembler): 数据转换工具类,如Dto转换为实体,实体转换为数据表pojo对象,基于org.mapstruct.Mapper实现
* 仓库层(repository): 仓库实现层,实体与DB之间存储的功能层
* 异常管理(exception): 封装具体业务的异常处理信息
* 配置模块(config): 封装配置信息,包括一些基础静态字段,基于阿波罗等获取的配置信息
* 枚举模块(enum): 封装该模块的枚举信息
* 数据库映射的基础数据对象(database): 命名规则为:XxxDo,数据表翻译为java基础的pojo对象
5.项目分层
- DDD层级分类:基于分层包,在每一个包下面,新建具体业务的名称,如在application.service包下面建立退款,售后补偿业务。建立两个分别为application.service.refund(退款包),application.service.compensate(售后包)。
- 业务分类:基于业务分层,在四层包的前提下,每一个业务均包括DDD的分层包。如下图所示:

DDD领域驱动设计-项目包结构说明-Ⅳ的更多相关文章
- 一个微服务+DDD(领域驱动设计)的代码结构示例
前有幸拜读过诸多大神关于DDD的实现落地等文章,学习较多,受益匪浅,在此推荐 : https://www.cnblogs.com/hafiz/p/9388334.htmlhttps://blog.cs ...
- C#进阶系列——DDD领域驱动设计初探(五):AutoMapper使用
前言:前篇搭建了下WCF的代码,就提到了DTO的概念,对于为什么要有这么一个DTO的对象,上章可能对于这点不太详尽,在此不厌其烦再来提提它的作用: 从安全上面考虑,领域Model都带有领域业务,让Cl ...
- 关于DDD领域驱动设计的理论知识收集汇总
原文:关于DDD领域驱动设计的理论知识收集汇总 最近一直在学习领域驱动设计(DDD)的理论知识,从网上搜集了一些个人认为比较有价值的东西,贴出来和大家分享一下: 我一直觉得不要盲目相信权威,比如不能一 ...
- DDD领域驱动设计初探(五):AutoMapper使用
前言:前篇搭建了下WCF的代码,就提到了DTO的概念,对于为什么要有这么一个DTO的对象,上章可能对于这点不太详尽,在此不厌其烦再来提提它的作用: 从安全上面考虑,领域Model都带有领域业务,让Cl ...
- DDD领域驱动设计落地实践(十分钟看完,半小时落地)
一.引子 不知今年吹了什么风,忽然DDD领域驱动设计进入大家视野.该思想源于2003年 Eric Evans编写的"Domain-Driven Design领域驱动设计"简称DDD ...
- C#进阶系列——DDD领域驱动设计初探(一):聚合
前言:又有差不多半个月没写点什么了,感觉这样很对不起自己似的.今天看到一篇博文里面写道:越是忙人越有时间写博客.呵呵,似乎有点道理,博主为了证明自己也是忙人,这不就来学习下DDD这么一个听上去高大上的 ...
- DDD领域驱动设计初探
DDD领域驱动设计初探1 前言:又有差不多半个月没写点什么了,感觉这样很对不起自己似的.今天看到一篇博文里面写道:越是忙人越有时间写博客.呵呵,似乎有点道理,博主为了证明自己也是忙人,这不就来学习下D ...
- DDD领域驱动设计
DDD领域驱动设计实践篇之如何提取模型 需求说明: 省级用户可以登记国家指标 省级用户和市级用户可以登记指标分解 登记国家指标时,需要录入以下数据:指标批次.文号.面积,这里省略其他数据,下同 登记指 ...
- DDD领域驱动设计初探(一):聚合
前言:又有差不多半个月没写点什么了,感觉这样很对不起自己似的.今天看到一篇博文里面写道:越是忙人越有时间写博客.呵呵,似乎有点道理,博主为了证明自己也是忙人,这不就来学习下DDD这么一个听上去高大上的 ...
随机推荐
- 【第二篇】- Git 安装配置之Spring Cloud直播商城 b2b2c电子商务技术总结
Git 安装配置 在使用Git前我们需要先安装 Git.Git 目前支持 Linux/Unix.Solaris.Mac和 Windows 平台上运行. Git 各平台安装包下载地址为:http://g ...
- .net Core 基于EF Core 实现数据库上下文
在做项目时,需要将某一些功能的实体建立在另一个数据库中,连接不同的数据库用以存储记录.通过查找资料,实现EF Core上下文. 下面是实现上下文后的解决方案的目录: 1.UpAndDownDbCont ...
- easyx小游戏
#include "stdafx.h" int main(){ srand(time(NULL)); initgraph(640,480); int user_x=20,user_ ...
- PHP的switch和ifelse谁更快?
对于多个if条件判断的情况下,我们使用switch来代替ifelse对于代码来说会更加的清晰明了,那么他们的效率对比呢?从PHP手册中发现有人已经对比过了,自己也用他的代码进行了实验: $s = ti ...
- dede5.7 标题长度限制修改
我们经常碰到dede标题长度不够用的问题20个字的标题有时候是真的有点短了网上也有些修改长度问题的帖子,但我发现都不完整所以写下来供大家参考下.免得浪费时间 第一步: 修改下面4处文件: dede目录 ...
- redis的持久化 与事务管理
1. redis的持久化 Redis的持久化主要分为两部分:RDB(Redis DataBase), AOF(Append Only File) 2. 什么是redis 的持久化 在指定 ...
- Sql 小技巧(持续汇总)
身份证号加密 select concat(left(`visitors`.`Card_id`,3),'****',right(`visitors`.`Card_id`,4)) AS `Card_id` ...
- 多个ssh key 配置多个网址
多个 ssh key 配置多个网站 一.生成ssh key ssh-keygen -t rsa -C "你的邮箱" -f ~/.ssh/id_rsa_one ssh-keygen ...
- 5分钟实现用docker搭建Redis集群模式和哨兵模式
如果让你为开发.测试环境分别搭一套哨兵和集群模式的redis,你最快需要多久,或许你需要一天?2小时?事实是可以更短. 是的,你已经猜到了,用docker部署,真的只需要十几分钟. 一.准备工作 拉取 ...
- AOJ/树与二叉搜索树习题集
ALDS1_7_A-RootedTree. Description: A graph G = (V, E) is a data structure where V is a finite set of ...