您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 
 订阅
从面向数据库到领域驱动设计
 
作者:kevin zou
   次浏览      
 2022-6-10
 
编辑推荐:
本文介绍面向数据库与面向对象、数据库查询、面向对象查询、预约服务传统实现及预约服务领域驱动实现。希望对您的学习有所帮助。
本文来自于知乎 ,由火龙果软件Linda编辑、推荐。

领域驱动设计(Domain Driven Design,简称DDD)一经提出,就引起很多人的关注,至今已有10余载(2004年,Eric Evans《领域驱动设计——软件核心复杂性应对之道》)。

主流的领域驱动设计里,概念众多,如实体、值对象、领域服务、资源库和聚合,六边形架构,CQRS,Event Source等。

众多的概念和理论,也让目前的领域驱动设计,实现复杂,难以落地。

一. 面向数据库与面向对象

领域驱动设计,实际上是一种面向对象的系统分析和设计方法。

传统开发,以数据库为中心。

数据集中存储在不同的table中,且为了满足关系模型理论,这些table的设计还需要符合各种范式和标准。

其业务逻辑通过一系列针对这些table的增删改查来实现。

领域驱动,则是面向对象。

数据分布在各个独立的对象里,各对象封装自己的内部数据和逻辑,对外只公开消息接口。

业务逻辑的实现表现为创建对象和向各个对象发送消息。

二. 数据库查询

不过要真正实现领域驱动设计,却非易事。

最困难的,在于不能摆脱对数据库的依赖,严格地说,是对数据库查询功能的依赖。

想象一下某ERP系统中存了几百万笔数据的采购单主档table,需要统计订单001中A材料目前的订购量。除了用SQL来sum(qty),不会有什么更好的方法了。

面向对象可以带来另一种思路,来看看下面这个例子:

一个会议室预约系统,预约会议室时,需要检查目前的预约记录,以防止时段冲突。

一般通过查询预约table :booking就可以实现,如下:

-- booking 中已有2笔当天A会议室的预约记录,以下SQL会查出第1笔数据,表示预约9/12 9:00~10:30的A会议室有冲突

--(某时段的结束时间如果大于要预约的开始时间,且其开始时间小于要预约的结束时间,那就表示时间区间有重叠)

SELECT *
FROM booking
WHERE booking_day = '20180912'
AND room_id = 'A'
AND end_time > '0900'
AND start_time < '1030'

 

这是传统的面向数据库的做法,有一个地方(table)存储了所有的预约数据,有一个可以按条件快速找到数据的查询功能(SELECT)。

三. 面向对象查询

面向对象的世界里,不会有这样的集中存储。

不过我们可以把数据存储到一个对象里,把查询数据库,改为找到那个对象。

比如这个例子,设计一个名(ID)为20180912-A的【日会议室预约对象】,里面存储了2018/9/12这一天A会议室的所有预约时段,这样就可以在预约9/12的A会议室时,通过预约日期和会议室ID先找到这个对象,再检查时段冲突。

//【20180912-A】对象里有2笔预约数据, 下列代码会检查出9:00~10:30会和第一笔8:00~10:00的预约有冲突

foreach (TimeRange bookinged in timeRangeList){

if(bookinged.EndTime.CompareTo(startTime) > 0 && bookinged.StartTime.CompareTo(endTime) < 0)

throw new BusException("ROOM_OCCUPIED");

}

 

把查询数据库,改为设计一个合适的查询对象,这是没有关系数据库和SQL的面向对象做法。

四. 预约服务传统实现

我们再通过实际代码来比较一下两者的差异,

首先是传统数据库的实现:

先是一些基本验证(日期,时间等),

然后再查数据库检查时段冲突,

最后Insert 数据到Booking table,完成预约会议室的功能。

写法可能有很多种,例如分DAL层,或者使用LINQ,不过本质上都是面向数据库,都是增删改查的过程。

五. 预约服务领域驱动实现

再来看一下面向对象的领域驱动设计实现:

服务层的接口和上面一样。选择用传统方式还是领域模型实现服务层,对于外部是透明的。

领域驱动的服务层,只是一个通往领域模型的入口。

预约会议室就是new一个Booking对象。

再来看看领域模型Booking对象:

一个Booking对象就是一次预约,记录下自己的数据后,再把预约消息发送给RoomDayBooking对象。

接下来是RoomDayBooking对象:

这个对象负责检查某会议室某天的时段冲突,因其内部存有那一天那个会议室所有的预约时段数据timeRangeList。

至于timeRangeList,和Booking对象里的subject,startTime没什么区别,只是数据类型是复杂类型,如果愿意,也可以用一个string来实现:

六. 两种思维方式的差异

再来比较一下面向对象思维和传统方式的差异:

如果是传统思维,可能是找到RoomDayBooking对象后,取得其预约数据,一一比较,检查冲突,最后再把新的时段存回RoomDayBooking对象。

即:取得数据 -> 加工处理 -> 写回数据

而面向对象思维,则是发送消息给RoomDayBooking对象,由对象自行负责其内部逻辑和数据存储。

RoomDayBooking开放预约接口,而不直接把数据timeRangeList给外部使用。

下面的活动图表达了面向对象发送消息的过程:

发消息给Booking,其负责存储预约数据;

发消息给RoomDayBooking,其负责检查时段冲突。

对象相对于数据库,最大的优势,是既可以存数据,还可以有逻辑,这样就可以把数据封装在对象内部,实现高内聚和低耦合。

七. 读写分离

到这里,还有一个重要问题,那就是任意查询怎么办?

例如要查询9/12~9/15全部会议室的预约状况,或者查询某个用户的所有预约数据。

答案是读写分离。

业务功能分为读服务和写服务。读服务是单纯的查询,其过程不会修改数据。而写服务则是系统的核心,是那些含有增删改过程的服务。

领域驱动只适用,也只需要专注写服务。

写服务如果需要查询,则设计专门的查询对象。

有一个DomainContext上下文对象,负责按ID取出领域对象,以及持久化领域对象。

领域对象透过ORM最后存储到数据库,UI和其它读服务使用SQL进行查询。

八. 结论

查询对象的建立,让整个领域驱动设计真正摆脱了对数据库的依赖,让我们可以更专注在领域模型的建立上。

只需要通过ID取得领域对象,大大降低了领域驱动设计基础设施实现的难度。

数据库可以延后设计,可以更快测试和验证核心逻辑。

查询功能仍然使用SQL和数据库,让领域驱动设计更接地气,可以真正落地实现。

分析建模阶段不仅涉及数据,还会涉及逻辑,让后续的开发更确定,更顺利。

领域驱动模型,实践了面向对象分析理论,利用它的封装特性,完成了优雅和简洁的设计。

其不仅适用于复杂系统,而是能像传统方式一样,可以普遍应用在信息系统的分析,设计和开发过程中。

最后附上其它一些代碼:

附一:取消预约的传统实现

附二:取消预约的领域驱动设计

服务层

Booking对象

RoomDayBooking对象

共用的BookingCommand对象(DTO)

附三:测试画面和結果

booking 7:00~8:00

save to database

booking 7:30~9:00 (error occurred)

   
次浏览       
相关文章

领域知识与限界上下文
深度解析DDD中台和微服务设计
领域建模的体系化思维与6种方法论
迄今为止最完整的DDD实践
 
相关文档

设计模式-原型模式
设计模式.组合模式
设计模式的六大原则实例
设计模式和代码重构
相关课程

JavaEE架构、 设计模式及性能调优
高质量软件设计与设计模式
设计模式及最佳实践
J2EE设计模式指南

最新活动计划
数据建模方法与工具 12-3[北京]
基于模型系统仿真与验证 12-14 [讲座]
白盒测试技术与工具实践 12-24[线上]
LLM大模型应用与项目构建 12-26[特惠]
UML和EA进行系统分析设计 12-20[线上]
SysML建模专家 1-16[北京]
 
 
最新文章
在EA中内嵌文档- Artifact
EA中模型视图
EA中的实体关系图
使用EA进行风险建模
EA中的项目词汇表
EA的模型导出或导入csv文件
自定义表格(Custom Table)在EA中的使用
Gap Analysis Matrix(差距分析矩阵)
更多...   
MBSE工具
MBSE平台
建模工具 EA
模型库-Model Center
需求管理-ReqManager
自动建模-Modeler
多级仿真-Sys Simulator
代码工程-Code Engineer
文档生成器-DocGenerator
更多...   
成功案例
广汽研究院 SysML+EA+软件分析设计
高合汽车研发部门 建模工具EA、WebEA、学习视频
国汽智联 建模工具EA、模型库、WebEA和iSpace
亿咖通 MBSE工程体系与工具链咨询
中航无人机 MBSE工具链
吉利汽车 购买EA工具
华科汽车零部件 购买EA工具
东风岚图汽车 购买EA工具 以及EA定制开发
更多...