zl程序教程

您现在的位置是:首页 >  .Net

当前栏目

读DDD有感

2023-04-18 14:06:51 时间

领域驱动设计

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 ObjectDAO)。DAO 的核心价值是封装了拼接 SQL、维护数据库连接、事务等琐碎的底层逻辑,让业务开发可以专注于写代码。但是如果业务逻辑改变时,则需要改动的代码量较多。

模型对象代码规范

  • Data Object:DO、数据对象,在DDD的规范里,DO应该仅仅作为数据库物理表格的映射,不能参与到业务逻辑中。
  • Entity实体对象:正常业务应该用的业务模型,它的字段和业务语言保持一致,和持久化方式无关。
  • DTO传输对象:Application层的入参和出参,Request、Response等都属于DTO的范畴,其价值在于适配不同的业务场景的入参和出参,避免让业务对象变成一个万能大对象。

DDD的结构

将对象转换为3+个对象。

User Interface为用户界面层(或表示层),负责向用户显示信息和解释用户命令。这里指的用户可以是另一个计算机系统,不一定是使用用户界面的人。

Application为应用层,定义软件要完成的任务,并且指挥表达领域概念的对象来解决问题。这一层所负责的工作对业务来说意义重大,也是与其它系统的应用层进行交互的必要渠道。应用层要尽量简单,不包含业务规则或者知识,而只为下一层中的领域对象协调任务,分配工作,使它们互相协作。它没有反映业务情况的状态,但是却可以具有另外一种状态,为用户或程序显示某个任务的进度。

Domain为领域层(或模型层),负责表达业务概念,业务状态信息以及业务规则。尽管保存业务状态的技术细节是由基础设施层实现的,但是反映业务情况的状态是由本层控制并且使用的。领域层是业务软件的核心,领域模型位于这一层。

Infrastructure层为基础实施层,向其他层提供通用的技术能力:为应用层传递消息,为领域层提供持久化机制,为用户界面层绘制屏幕组件,等等。基础设施层还能够通过架构框架来支持四个层次间的交互模式。

DDD结构一

分层:
  • Application层
  • Domain层
  • Infrastructure层
  1. User Interface为用户界面层(或表示层),负责向用户显示信息和解释用户命令。这里指的用户可以是另一个计算机系统,不一定是使用用户界面的人。
  2. Application为应用层,定义软件要完成的任务,并且指挥表达领域概念的对象来解决问题。这一层所负责的工作对业务来说意义重大,也是与其它系统的应用层进行交互的必要渠道。应用层要尽量简单,不包含业务规则或者知识,而只为下一层中的领域对象协调任务,分配工作,使它们互相协作。它没有反映业务情况的状态,但是却可以具有另外一种状态,为用户或程序显示某个任务的进度。
  3. Domain为领域层(或模型层),负责表达业务概念,业务状态信息以及业务规则。尽管保存业务状态的技术细节是由基础设施层实现的,但是反映业务情况的状态是由本层控制并且使用的。领域层是业务软件的核心,领域模型位于这一层。
  4. 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中应遵循:

  1. 接口名称不应该使用底层实现的语法:insert、select、update、delete都属于SQL语法,这几个词相当于和DB底层实现做了强绑定,我们应该把Repository当成一个中性的Collection的接口。
  2. 出参和入参不应该使用底层数据格式Respository不应该直接操作底层的DO,其接口实际上应该存在于domain层,根本看不到DO的实现。避免底层实现逻辑渗透到业务代码。
  3. 应该避免所谓的“通用”Repository模式

DDD的开源应用项目

DDD的开源应用项目