基于DDD领域驱动设计的思想,在开发具体系统时,需要先建立不同的层级包。主要是梳理不同层面(应用层,领域层,基础设施层,展示层)包括的功能目录,每一个层面应该包括哪些模块。本例所讲述的分层是DDD落地方案中常用的一种(参考),且本例适当做了调整和细化。详细分层目录参考下图:

1. 展示层

展现层(用户接口层)(Presentation Layer):负责以Restful的格式接受Web请求,然后将请求路由给Application层执行,并返回视图模型(View Model),其载体通常是DTO(Data Transfer Object)。
* 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 Layer):主要负责获取输入,组装上下文,做输入校验,调用领域层做业务处理,如果需要的话,发送消息通知。当然,层次是开放的,若有需要,应用层也可以直接访问基础实施层。
* application 应用层
* 相对于领域层,应用层是很薄的一层,应用层定义了软件要完成的任务,要尽量简单.
* 它不包含任务业务规则或知识, 为下一层的领域对象协助任务、委托工作。这一层也很适合写一些任务处理,消息处理
* 它没有反映业务情况的状态,但它可以具有反映用户或程序的某个任务的进展状态。
*
* 对外:为展现层提供各种应用功能(service)。
* 对内:调用领域层(领域对象或领域服务)完成各种业务逻辑任务
*
* 事件(event): 对象命名为XxxEvent,跨聚合根,或部分业务处理完成后,需要通知其他模块的,本例采用 Spring event模式。本例是将领域事件放在应用层的。
* 应用服务(service): 对象命名为XxxService,应用层的服务
*
* 一个应用层通常包括以下三种服务:
*
* 业务处理类:XxxCommandService
* 业务查询类:XxxQueryService
* 业务事件类:XxxEventService
特别说明:一个实体处理完成后,若存在副作用,可基于事件模式处理。关于事件模块到底是放置在领域层还是应用层,网上存在不同的模式(参考网址:DDD-领域事件)。本例是基于Spring Event模式,放在应用层的。

3. 领域层

领域层(Domain Layer):主要是封装了核心业务逻辑,并通过领域服务(Domain Service)和领域对象(Entities)的函数对外部提供业务逻辑的计算和处理。
* 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 Layer)主要包含Tunnel(数据通道)、防腐层,Config和Common。这里我们使用Tunnel这个概念来对所有的数据来源进行抽象,这些数据来源可以是数据库(MySQL,NoSql)、搜索引擎、文件系统、也可以是SOA服务等;Config负责应用的配置;Common是通用的工具类。
* infrastructure 基础实施层
* 向其他层提供 通用的 技术能力(比如工具类,第三方库类支持,常用基本配置,数据访问底层实现)
* 基础实施层主要包含以下的内容:
* 为应用层 传递消息(比如通知)
* 为应用层 提供持久化机制(最底层的实现)
*
* 防腐层(acl): 实体对接外部系统,实体与外部系统之间,不同领域之间,不同的参数转换,语义转换等
* 转换层(assembler): 数据转换工具类,如Dto转换为实体,实体转换为数据表pojo对象,基于org.mapstruct.Mapper实现
* 仓库层(repository): 仓库实现层,实体与DB之间存储的功能层
* 异常管理(exception): 封装具体业务的异常处理信息
* 配置模块(config): 封装配置信息,包括一些基础静态字段,基于阿波罗等获取的配置信息
* 枚举模块(enum): 封装该模块的枚举信息
* 数据库映射的基础数据对象(database): 命名规则为:XxxDo,数据表翻译为java基础的pojo对象

5.项目分层

一个微服务里,通常包括多个不同的领域业务。一个领域业务基于DDD的模式,通常都包括上述的分层模块,为了区分不同的领域业务,有两种方案建立包的层级。
  1. DDD层级分类:基于分层包,在每一个包下面,新建具体业务的名称,如在application.service包下面建立退款,售后补偿业务。建立两个分别为application.service.refund(退款包),application.service.compensate(售后包)。
  2. 业务分类:基于业务分层,在四层包的前提下,每一个业务均包括DDD的分层包。如下图所示:
本例选用的方案2,便于归类业务在各个层的模块代码。最后层级结构确定下来后,每个层只负责该层应该负责的功能,不可混用,滥用。好的设计需要开发人员遵守一定的规则,关于层级划分,没有绝对的标准,可参考开源COLA 4.0或其他架构学习。
 

DDD领域驱动设计-项目包结构说明-Ⅳ的更多相关文章

  1. 一个微服务+DDD(领域驱动设计)的代码结构示例

    前有幸拜读过诸多大神关于DDD的实现落地等文章,学习较多,受益匪浅,在此推荐 : https://www.cnblogs.com/hafiz/p/9388334.htmlhttps://blog.cs ...

  2. C#进阶系列——DDD领域驱动设计初探(五):AutoMapper使用

    前言:前篇搭建了下WCF的代码,就提到了DTO的概念,对于为什么要有这么一个DTO的对象,上章可能对于这点不太详尽,在此不厌其烦再来提提它的作用: 从安全上面考虑,领域Model都带有领域业务,让Cl ...

  3. 关于DDD领域驱动设计的理论知识收集汇总

    原文:关于DDD领域驱动设计的理论知识收集汇总 最近一直在学习领域驱动设计(DDD)的理论知识,从网上搜集了一些个人认为比较有价值的东西,贴出来和大家分享一下: 我一直觉得不要盲目相信权威,比如不能一 ...

  4. DDD领域驱动设计初探(五):AutoMapper使用

    前言:前篇搭建了下WCF的代码,就提到了DTO的概念,对于为什么要有这么一个DTO的对象,上章可能对于这点不太详尽,在此不厌其烦再来提提它的作用: 从安全上面考虑,领域Model都带有领域业务,让Cl ...

  5. DDD领域驱动设计落地实践(十分钟看完,半小时落地)

    一.引子 不知今年吹了什么风,忽然DDD领域驱动设计进入大家视野.该思想源于2003年 Eric Evans编写的"Domain-Driven Design领域驱动设计"简称DDD ...

  6. C#进阶系列——DDD领域驱动设计初探(一):聚合

    前言:又有差不多半个月没写点什么了,感觉这样很对不起自己似的.今天看到一篇博文里面写道:越是忙人越有时间写博客.呵呵,似乎有点道理,博主为了证明自己也是忙人,这不就来学习下DDD这么一个听上去高大上的 ...

  7. DDD领域驱动设计初探

    DDD领域驱动设计初探1 前言:又有差不多半个月没写点什么了,感觉这样很对不起自己似的.今天看到一篇博文里面写道:越是忙人越有时间写博客.呵呵,似乎有点道理,博主为了证明自己也是忙人,这不就来学习下D ...

  8. DDD领域驱动设计

    DDD领域驱动设计实践篇之如何提取模型 需求说明: 省级用户可以登记国家指标 省级用户和市级用户可以登记指标分解 登记国家指标时,需要录入以下数据:指标批次.文号.面积,这里省略其他数据,下同 登记指 ...

  9. DDD领域驱动设计初探(一):聚合

    前言:又有差不多半个月没写点什么了,感觉这样很对不起自己似的.今天看到一篇博文里面写道:越是忙人越有时间写博客.呵呵,似乎有点道理,博主为了证明自己也是忙人,这不就来学习下DDD这么一个听上去高大上的 ...

随机推荐

  1. C# 反射 + Quartz,实现流程处理

    场景: 前不久,公司里项目经理要求我实现流程处理,比如,用户可以定义一个定时任务,每周一查看报表.定时任务很简单,用Quartz可以实现,但是用户自己选择报表就比较麻烦,因为系统的不同模块的生成报表的 ...

  2. 技术栈:springboot2.x,vue,activiti5.22,mysql,带工作流系统

    前言 activiti工作流,企业erp.oa.hr.crm等审批系统轻松落地,请假审批demo从流程绘制到审批结束实例. 一.项目形式 springboot+vue+activiti集成了activ ...

  3. scrum项目冲刺_day08总结

    摘要:今日完成任务. 1.短信服务正在进行 2.注册登录功能基本实现,但缺少短信验证 3.导航在进行 4.搜索功能基本完成 总任务: 一.appUI页面(已完成) 二.首页功能: 1.图像识别功能(已 ...

  4. ecshop商品自定义销量(虚拟销量)实现方法

    1.在sq执行语句   ALTER TABLE `ecs_goods` ADD `sales_volume_base` INT( 10 ) UNSIGNED NOT NULL DEFAULT '0' ...

  5. UML类图及其JAVA的代码实现

    推荐 : https://my.oschina.net/u/3635618/blog/3165129 http://www.uml.org.cn/oobject/201104212.asp

  6. JDBC-3(Transcation) ****

    3.1 异常的使用说明 在工具类中(JDBCUtils)的方法最好声明异常(throws),以便后续实现类中去捕获这些异常. 工具类中捕获异常通常没有意义 eg:实现类中connection建立过程出 ...

  7. Jenkins持续交付实战演练

    jenkins web hook机制 运行jenkins任务触发方式: 主动运行 定时构建 就算代码库没有更新,也会构建. 通过代码库主动触发Jenkins的构建任务 jenkins向外暴露一个触发器 ...

  8. 启动jemeter 报错相关解决方案

    1:当启动jemeter时报错"页面文件太小,无法完成操作" 如图: 是说明分配的内容不足,即可调整内存重启即可解决 1):打开:控制面板>系统和安全>系统 2):点击 ...

  9. HTML对溢出的控制:overflow

    用于对超出模块的内容进行控制 overflow的三种参数 1.visible(默认):溢出部分可见 2.hidden:溢出部分隐藏 3.auto:适当加入滚动条 overflow使用方法 1.常用 o ...

  10. T-SQL——函数——字符串操作函数

    目录 0. 加号(+) 1. LEFT和RIGHT 2. SUBSTRING 3. LEN和DATALENGTH 4. CHARINDEX和PATINDEX 5. REPLACE 6. REPLICA ...