读DDD有感
Posted 爱叨叨的程序狗
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读DDD有感相关的知识,希望对你有一定的参考价值。
领域驱动设计
Domain-driven design,缩写DDD
,是对业务的抽象,把业务模型反形成系统架构设计的一种方式。通过数据对象解决业务问题。
A domain model (the term is not at all Java specific) is a class that models something in the problem domain, as opposed to a class that exists for technical implementation reasons.
Domain model instances often need to be persisted in a database, and in Java, they typically conform to the Java Beans specification, i.e. they have get and set methods to represent individual properties and a parameterless constructor. Spring and other frameworks allow you to access these properties directly in your JSPs.
For example, in a shop application, some of your domain model classes would be Product, Order, ShoppingCart and Customer.
传统的ER模型
Entity(实体)这个词在计算机领域的最初应用可能是来自于 Peter Chen 在 1976 年的 “The Entity-Relationship Model - Toward a Unified View of Data"(ER 模型),用来描述实体之间的关系,而 ER 模型后来逐渐的演变成为一个数据模型,在关系型数据库中代表了数据的储存方式。
E:表示实体(实体转换为数据库重的一个表)
R:表示关系(两个实体对应的规则,一对一、一对多、多对多)
三范式:
①:列不可拆分
②:唯一标识
③:因为主键
传统的ER模式是一种贫血模型。
模型下领域对象的作用很简单,只有所有属性的get/set方式、少量简单的属性值转换,不包含任何业务逻辑,不关系对象持久化,只是作为数据对象的承载和传递的介质。
Repository 的价值
数据库驱动开发中,我们适用Data Access Object
(DAO
)。DAO
的核心价值是封装了拼接 SQL
、维护数据库连接、事务等琐碎的底层逻辑,让业务开发可以专注于写代码。但是如果业务逻辑改变时,则需要改动的代码量较多。
模型对象代码规范
Data Object
:DO、数据对象,在DDD
的规范里,DO应该仅仅作为数据库物理表格的映射,不能参与到业务逻辑中。- Entity实体对象:正常业务应该用的业务模型,它的字段和业务语言保持一致,和持久化方式无关。
DTO
传输对象:Application层的入参和出参,Request、Response等都属于DTO
的范畴,其价值在于适配不同的业务场景的入参和出参,避免让业务对象变成一个万能大对象。
DDD的结构
将对象转换为3+个对象。
User Interface为用户界面层(或表示层),负责向用户显示信息和解释用户命令。这里指的用户可以是另一个计算机系统,不一定是使用用户界面的人。
Application为应用层,定义软件要完成的任务,并且指挥表达领域概念的对象来解决问题。这一层所负责的工作对业务来说意义重大,也是与其它系统的应用层进行交互的必要渠道。应用层要尽量简单,不包含业务规则或者知识,而只为下一层中的领域对象协调任务,分配工作,使它们互相协作。它没有反映业务情况的状态,但是却可以具有另外一种状态,为用户或程序显示某个任务的进度。
Domain为领域层(或模型层),负责表达业务概念,业务状态信息以及业务规则。尽管保存业务状态的技术细节是由基础设施层实现的,但是反映业务情况的状态是由本层控制并且使用的。领域层是业务软件的核心,领域模型位于这一层。
Infrastructure层为基础实施层,向其他层提供通用的技术能力:为应用层传递消息,为领域层提供持久化机制,为用户界面层绘制屏幕组件,等等。基础设施层还能够通过架构框架来支持四个层次间的交互模式。
DDD结构一
分层:
- Application层
- Domain层
- Infrastructure层
- User Interface为用户界面层(或表示层),负责向用户显示信息和解释用户命令。这里指的用户可以是另一个计算机系统,不一定是使用用户界面的人。
- Application为应用层,定义软件要完成的任务,并且指挥表达领域概念的对象来解决问题。这一层所负责的工作对业务来说意义重大,也是与其它系统的应用层进行交互的必要渠道。应用层要尽量简单,不包含业务规则或者知识,而只为下一层中的领域对象协调任务,分配工作,使它们互相协作。它没有反映业务情况的状态,但是却可以具有另外一种状态,为用户或程序显示某个任务的进度。
- Domain为领域层(或模型层),负责表达业务概念,业务状态信息以及业务规则。尽管保存业务状态的技术细节是由基础设施层实现的,但是反映业务情况的状态是由本层控制并且使用的。领域层是业务软件的核心,领域模型位于这一层。
- Infrastructure层为基础实施层,向其他层提供通用的技术能力:为应用层传递消息,为领域层提供持久化机制,为用户界面层绘制屏幕组件,等等。基础设施层还能够通过架构框架来支持四个层次间的交互模式。
传统的四层架构都是限定型松散分层架构,即Infrastructure层的任意上层都可以访问该层(“L”型),而其它层遵守严格分层架构
其他结构见下文链接。
作者:张晓龙
链接:https://www.jianshu.com/p/a775836c7e25
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
DO | Entity | DTO | |
---|---|---|---|
目的 | 数据库表映射 | 业务逻辑 | 适配业务场景 |
代码层级 | Infrastructure | Domain | Application |
命名规范 | XxxDO | Xxx | XxxDTO XxxCommand XxxRequest 等 |
字段名称标准 | 数据库表字段名 | 业务语言 | 和调用方商定 |
字段数据类型 | 数据库字段类型 | 尽量是有业务含义的类型,比如DP | 和调用方商定 |
是否需要序列化 | 不需要 | 不需要 | 需要 |
转化器 | Data Converter | Data Converter DTO Assembler | DTO Assembler |
从使用复杂度角度来看,区分了DO、Entity、DTO
带来了代码量的膨胀(从1个变成了3+2+N个)。但是在实际复杂业务场景下,通过功能来区分模型带来的价值是功能性的单一和可测试、可预期,最终反而是逻辑复杂性的降低。
DDD
Repository代码规范
传统Data Mapper(DAO
)属于“固件”,和底层实现(DB、Cache、文件系统等)强绑定,如果直接使用会导致代码“固化”。
在DDD
中应遵循:
- 接口名称不应该使用底层实现的语法:insert、select、update、delete都属于
SQL
语法,这几个词相当于和DB底层实现做了强绑定,我们应该把Repository当成一个中性的Collection的接口。 - 出参和入参不应该使用底层数据格式:
Respository
不应该直接操作底层的DO,其接口实际上应该存在于domain层,根本看不到DO的实现。避免底层实现逻辑渗透到业务代码。 - 应该避免所谓的“通用”Repository模式
DDD的开源应用项目
以上是关于读DDD有感的主要内容,如果未能解决你的问题,请参考以下文章