读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 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
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

DOEntityDTO
目的数据库表映射业务逻辑适配业务场景
代码层级InfrastructureDomainApplication
命名规范XxxDOXxxXxxDTO XxxCommand XxxRequest
字段名称标准数据库表字段名业务语言和调用方商定
字段数据类型数据库字段类型尽量是有业务含义的类型,比如DP和调用方商定
是否需要序列化不需要不需要需要
转化器Data ConverterData Converter DTO AssemblerDTO 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的开源应用项目

以上是关于读DDD有感的主要内容,如果未能解决你的问题,请参考以下文章

读《梦断代码》第2章有感

查看发票组代码后的总结和有感

读《梦断代码》第0章有感

读《大道至简》有感(伪代码)

读《代码整洁之道》有感

第九次读书笔记——读《代码整洁之道》有感