Action On DDD

Stella981
• 阅读 705

Action On DDD

常见的开发方式

MVC贫血模型

最常见的开发模式传统EJB开发时提倡的开发模式,是通过算法调用数据对象的getter/setter方法修改数据,再将数据存储起来的过程。

在MVC下,常见的模式是controller层中通过一部分算法判断数据对象的数据是否符合业务需要,在service中通过另一部分算法按照规则业务规则修改数据分别调用不同dao将数据更新或存储起来。

优点:

简单逻辑场景开发快,实现简单。

服务化后通信时传送的对象简洁高效

缺点:

复杂逻辑场景下,代码冗长难懂,维护困难。

代码逻辑和业务逻辑的直接关联度低,在没有注释的情况下其它人很难通过代码了解业务场景。

代码耦合度很高,难以避免出现“上帝类”的情况。

评价:

数据喂机器的开发方式,特别适合有大量表单录入的系统,对业务逻辑的表现能力差,复杂业务场景维护困难。

关于领域驱动实现的方式

核心点:领域驱动是将业务功能限制在特定领域进行划分后,专注于某些特定领域的开发方式,它的最佳实现是领域自治,即领域内的对象(聚合根)自身仅能管理自己的数据和状态,这样避免了领域对象相互污染的情况。领域驱动关心的是领域对象是什么,而不是对象做什么。

例如:转账行为中,领域关注的核心概念是 “账户(Account)”,而不是日志,但是根据业务需求需要在转账进行的过程中写入日志。为了完成业务需要,我们在账户金额变动的过程中不得不加入日志写入的行为逻辑:

class Account{

AccountLog accountLog;

// 方法内不得不集成了日志写入操作

void reduce(BigDecimal amount){

//...

accountLog.writeReduceLog(accountId,amount);

//...

}

}

我们发现,为了执行一个与领域内无关的操作,不得为了业务需要引入一个领域外的对象,导致Account对象领域被污染。

DCI

DCI是数据Data 场景Context 交互Interactions的简称,DCI是一种特别关注行为的模式(可以对应GoF行为模式),由MVC模式提出者Trygve Reenskaug提出。

Trygve Reenskaug认为数据Data应当是静态的,即数据本身不能有动作(你见过表格自己填写自己的吗?),但是数据反应了一个对象的状态。

如果要想让数据能够执行各种行为则需要将数据放入角色模型(Role Model)中,由角色模型驱动完成数据变更 (假设PersonData反应了一个人的基本信息,则如果想让这个人去工作,则必须将PersonData 放入Worker角色中)。

协作交互模型(Collaboration Model)则是驱动角色模型如何动作的关键,如果我们需要角色们协调起来去完成某个业务场景,则必须通过协作交互模型来进行(上个例子提到的Worker,如果需要执行放款操作,则还需要与对应的Account角色进行交互)。

对于DCI实现的领域驱动设计,Role和Collaboration(即Interactions)才是真正的领域模型,Context和Data则更面向于程序,由Context准备好足够的程序组件和Data,让数据通过协作模型和角色模型完成一系列动作,再将得到的Data进行存储的。

评价:

与传统Evans提倡的DDD模型略有不同,Evans提倡领域自治,即模型的数据由自己更新,DCI则是将数据分离更新。在实践过程中,DCI架构更像是一个完整的场景剧的表演过程,由Context为角色Role准备表演的“舞台”,舞台中包括了各种各样的必要设施,角色们只要根据剧本Collaboration进行表演即可,最后得到的数据是角色本身的完结状态。

CQRS

命令查询的责任分离Command Query Responsibility Segregation (简称CQRS)模式是一种架构体系模式,能够使改变模型的状态的命令和模型状态的查询实现分离。

Action On DDD

当一个Command进来时,从仓储Repository加载一个聚合aggregate对象群,然后执行其方法和行为。这样,会激发聚合对象群产生一个事件,这个事件可以分发给仓储Repository,或者分发给Event Bus事件总线,比如JavaEE的消息总线等等。事件总线将再次激活所有监听本事件的处理者。当然一些处理者会执行其他聚合对象群的操作,包括数据库的更新。

查询时,则通过查询优化的数据库直接进行查询(典型的有将数据冗余在搜索引擎中查询或直接生成报表在数据库查询)

评价:

该架构的较为复杂,在实现起来也较为困难(特别在Spring框架下),由于数据的存储和更新都是通过事件进行,在整个系统中会出现大量不同类型的事件,在实现过程服务化的情况下,要保证游离在领域对象中的数据与数据库中的数据一致,不得不进行锁处理,不太适合传统的服务化和微服务化架构 。适合该模式开发的典型框架是Akka Actor,这是由于在Akka集群中,领域对象(Actor)由且仅有一个,不会因为并发出现多个相同的Actor。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
3年前
Nginx反向代理upstream模块介绍
!(https://oscimg.oschina.net/oscnet/1e67c46e359a4d6c8f36b590a372961f.gif)!(https://oscimg.oschina.net/oscnet/819eda5e7de54c23b54b04cfc00d3206.jpg)1.Nginx反
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这