领域驱动设计 pdf_什么是领域驱动设计?

什么是领域驱动设计?

你可能使用领域驱动设计(DDD)开发了一些项目。你可能很满意, 使用领域模型来开发领域业务。并且得意地展示给你的同事看,他们会说“666”。

但有的时候你使用领域模型你总觉得哪儿有点不对劲。你会嘀咕你可能遗漏了什么。 emmmm...但真的是这样吗?你发觉自己在问类似下面的这些问题:

  • 什么是领域模型?
  • 领域模型是怎么更新到数据库的呢?
  • 领域模型是否要引入一种架构模式?例如CQRS

当我刚开始使用领域模式的时候,我也同样被上面这些问题所困扰。 甚至当我写文档前几天,我也并没有扎实地掌握某些细节。 我经历了一些“啊哈”的开窍时刻,我想把这些分享给你。 这篇文章会深入讲解帮你明白上面问题的答案。

在看答案之前,我们需要先往后退一步。 这篇文章的目的不是给你一个要点清单,而是想帮你真正地领会领域模型。 其实我们并没有太多需要学习的,事实上,我们会花很多时间试图忘记某些已经习得的概念(unlearning)。

“忘记你已经学到的。” — Yoda

a30b7968b3a42a594b2b90d5e32b614f.png

这篇文章真的很长。它更像一本mini书,这也是我更喜欢的形式。


摘要

如果你不想阅读整篇文章,可以快速浏览这份摘要。如果你打算阅读整篇文章,你完全可以跳过这部分。

Question:什么是领域模型?

为解决场景下的问题而形成的一套模型,然后使用这套模型来解决业务问题。 根据重复劳动经验我们会形成一套模式。领域模型也一样会形成一套模式,他包括:实体、值对象、模块、领域服务。

Question:领域模型是怎么更新到数据库的呢?

使用资源库(repository)将领域模型更新到数据库。 在一个一对多的实体,例如:用户组(Group)和用户(User),用户组内有N个用户, 如果用户非常多,一次加载Group肯定会造成性能损失,这种问题怎么设计呢? 如果不使用领域模型依靠经验你会想到拆分,现在你使用了领域模型想的方案也应该是拆分。 我看到有些人把repository注入到领域模型内,这种做法是错误的。

Question:领域模型是否要引入一种架构模式?例如CQRS

首先我想说的是领域模型不需要引入架构模式。 领域模式是解决领域内的业务问题的,他不是解决架构问题,所以领域模型本身不需要引入架构。 当你使用领域模型的时候,领域层之上你可以使用架构,比如CQRSMVC等等。


要不,我们开始正文。我想从传统的项目开始讲解一步步的过渡到领域模型。 我将讲解三种组织代码的结构,分别是:传统模式、IDDD模式、我思考的模式。

说一下我们用到的技术框架:

  • ORM:Spring Data JPA
  • Database:h2-database

我们先假设一个需求用例,现在我们要开发一个身份认证模块(identity)其中包括的功能有 获得用户信息、修改密码、用户认证。

使用传统项目来开发整个需求

首先来看下我们的项目结构:

b7a547934fec395a7ed8748121f70ef6.png

这个项目结构大家已经非常熟悉了,就是我们传统的分层方式。 我们通常会把业务逻辑写在service里面,如下:

79032d97a93395085ed831488a22a1c5.png

整个功能我们已经开发完了,是不是看着非常简单。 我们来看changePassword方法,我们通过repository根据用户名获得到用户, 然后调用authenticate方法进行认证,认证通过后修改密码(user.setPassword())。 是不是看上去没有任何毛病,而且程序还运行的非常成功。嗯,确实是。 但是在这种编程模式里我们更多的是从数据库的模式来开发的,因为User只是封装了静态数据。 然后在service中来完成修改密码这个逻辑,这种操作更像是过程化编程。

我们应该从面向对象的角度来思考问题。 一提到对象你首先想到的是什么?继承?封装?多态?还有吗? 我再添一条类是一组相关的属性和行为的集合

既然我提到了属性和行为,那我们重新思考下修改密码这个用例: 首先passwordUser类上的一个属性,对于修改密码我们应该是调用User对象上的changePassword方法, 然后由changePassword来完成修改password属性,这就是封装。

接下来我们使用领域模型再来完成上面用例的业务。

使用IDDD来开发整个需求

首先我们也是来看一下IDDD的项目结构:

6a7d1db2c1341286d1a3137eb10dc347.png

当你看到这个项目结构的时候,你可能心生疑惑:“怎么没有service, repository这样的包呢?”

我来告诉你,IDDD推荐我们使用应用层、领域层和基础设施层来做分层。 对于这种分包方式是《实现领域驱动设计》这本书比较推荐的。所以这个项目我们以这种方式来组织我们的代码。

接下来我们来看看应用层服务和领域模型:

bfabf2543bde410c2b38a15e3ea27c59.png

36de0a9c81ac81e7a1ff55a0b180d679.png

再来看UserService上的changePassword方法,我们还是通过authenticate获得用户, 然后又调用了用户的changePassword来修改密码。

但是你会发现我们并没有把密码加密这个交由User来完成,这是为什么呢?

因为加密不是User的职责。就像authenticate一样,你自己不可能认证自己, 就像你不借助镜子永远不会看清你的脸蛋。就像你会问别人我今天漂不漂亮,而不会自欺欺人的告诉自己我很漂亮。

通过将changePassword交由User,你会发现你的业务很清晰了。 因为你对号入座将原本由用户该做的事情又还给了用户。

接下来我想说一个我认为的分层架构,以及如何组织代码。这部分知识涉及到了UML、面向对象。

我直接上图,然后在细细讨论:

b15d9976c1c7454992bf0e9281af7661.png

当你看到这个结构,你会发现怎么没有层了呢?怎么都放在了一个包里。 聊到这我就应该给你说一说UML中的模块和构造型。 我们都已经很熟悉模块了,因为我们平常都是在用包来组织模块。 这个我就不多讲了,我想说的什么是构造型。构造型就是用来区分不同种类的类。 玩了那么多年的Spring,还记得那几个常用的组件注解(@Component@Controller@Service@Repository)吗? 他们被放置在org.springframework.stereotype这个包下,就是为了区分你的不同种类的类。

所以我们现在为我们的模块(identity)画一个UML的类图:

f7813f92bac83e50a30d7587c73c4878.png

430a2d96734524862c19e3d1d8f15984.png

当你看到UML的类图再和刚才的Java项目结构图进行对比是不是有些清晰了呢? 这个时候你可以再配合一个用例和时序图,来表达你的业务。

40b3f505fe06a2acaddff09a201b231f.png

整个示例源码

what-is-a-domain-model-example

结束

也大体说完了整个演变过程,这也是我一年了的技术总结吧。

为了搞清楚心中的一个疑惑:“为什么我们项目的代码组织结构和国外开源框架的组织结构有那么大的不同呢。” 我花了一年的时间看完了:《领域驱动设计》、《实现领域驱动设计》、 《企业应用架构模式》、《软件建模与设计》这几本书,其实还有正在看没有看完的。

当你想搞懂一个东西的时候,你应该把他搞到通透,然后再说你怎么看待这个问题。 有的时候我在看完DDD以后,我还是会问自己,这是我想要的吗?出现这种疑惑还是需要攀登, 你应该继续选择研究这本书引用其他知识,知识的传播可能是书籍也可能是论文。 当把这些迭代的思想看完以后,你还得回过头来在看这个问题,再去揣摩。可能会有新的突破。 只有这样一次次的突破,才能解决你心中的疑惑。

还有很多细节我可能没有一一表达出来。 上述演变过程仅代表我个人思考,禁止转载,如有误人子弟之处,请您指出。

如有问题请加QQ群讨论:

4affb52139467608937a09aa8e7ddb94.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/245545.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android四级缓存,RecyclerView 源码四级缓存原理

入口我们从使用功能上去读取源码,通常的用法是这个样子-> 我们设置layoutmanager,GridLayouManager 继承LinearLayoutManager,所以我们就LinearLayoutManager 为基准查看rv.layoutManager GridLayoutManager(this,5)rv.addItemDecoration…

shell脚本发邮件内容html,[转]Shell脚本中发送html邮件的方法

作为运维人员,免不了要编写一些监控脚本,并将监控结果及时的发送出来。那么通过邮件发送是比较常用的一种通知方式了。通常的,如果需要发送的内容是简单的文本文件,那么使用/bin/mailx就可以了,但是如果想要发送更复杂…

HTML打开网页拒绝访问,192.168.1.1拒绝访问怎么办?

问:为什么设置路由器时,在浏览器中输入192.168.1.1,结果显示拒绝访问,这个问题怎么解决?答:如果是在设置路由器的时候,登录192.168.1.1被拒绝访问,多半是你自己操作有问题导致的&…

gitlab git clone 输入密码_gitlab1:部署gitlab

1、配置yum源vim /etc/yum.repos.d/gitlab-ce.repo复制以下内容:[gitlab-ce]nameGitlab CE Repositorybaseurlhttps://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/gpgcheck0enabled12、更新本地yum缓存sudo yum makecache3、安装GitLab社区版sudo y…

python播放在线音乐_Python实现在线音乐播放器

最近这几天,学习了一下python,对于爬虫比较感兴趣,就做了一个简单的爬虫项目,使用Python的库Tkinsert做了一个界面,感觉这个库使用起来还是挺方便的,音乐的数据来自网易云音乐的一个接口,通过re…

golang如何打印float64的整数部分_2020-08-10:如何不用加减乘除求浮点数的2倍值?...

福哥答案2020-08-10:浮点数符号位阶码尾数,阶码加1就是浮点数的2倍值。代码用golang编写,如下:package test33_addimport ( "fmt" "math" "testing")/*//https://www.bbsmax.com/A/6pdDX7…

mysql varchar 非空判断_工资从1万到3万,你还差mysql数据库优化之系列三

查询性能的优化优化查询分析的步骤:1.应用查询是否检索超过需要的数据2.mysql服务器是否在分析超过需要的数据正确使用索引:1.like语句操作一般不使用%或_开头例如: select * from tableName where name like %cn;只能使用like aaa%;2.组合索引例如索引index index_name (a, b,…

etl数据抽取工具_数据同步工具ETL、ELT傻傻分不清楚?3分钟看懂两者区别

什么是数据同步工具(ETL、ELT)数据同步工具ETL或者ELT的作用是将业务系统的数据经过抽取、清洗转换之后加载到数据仓库的过程,目的是将企业中的分散、零乱、标准不统一的数据整合到一起,为企业的决策提供分析依据。数据同步是大数据项目重要的一个环节。…

oracle数据库查表_Oracle面试问题-技术篇

这也许是你一直期待的文章,在关注这部分技术问题的同时,请务必阅读有关面试中有关个人的问题和解答。和猎萝卜小编来一起了解。这里的回答并不是十分全面,这些问题可以通过多个角度来进行解释,也许你不必在面试过程中给出完全详尽…

uniapp怎么调起摄像头拍视频_抖音视频怎么拍?我们总结了10个手机视频拍摄小技巧...

抖音的很多功能与小咖秀类似,但不同的是,抖音用户可以通过视频拍摄的快慢、视频编辑和特效等技术让作品更具创造性,而不是简单地对嘴型。抖音短视频的10个拍摄技巧,帮助你方便、快捷地制作出更加优质的短视频内容。1.远程控制暂停更方便抖音视频怎么拍?在拍摄时,如果…

jdk 安装_Jdk 安装使用教程

java 程序员的第一个程序 hello worldpublic class MyFirstJavaProgram {public static void main(String []args) {System.out.println("Hello World");}}1、下载jdk连接地址:https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_o…

win10计算机管理字体糊,win10字体模糊如何解决

win10系统是一款优秀的消费级别的系统,深受大家广泛好评。但是有些网友在使用时也会出现一些问题,比如win10字体模糊。接下来,我就给大家介绍一下解决win10字体模糊的解决方法,赶紧来瞧瞧吧近来有不少网友询问win10字体模糊的解决…

蓝字冲销是什么意思_梦见上学 做梦梦到上学是什么意思 梦到上学有哪些预兆...

点击上方蓝字关注我们 查看更多梦见上学是什么意思 做梦梦到上学是什么意思 梦到上学有哪些预兆梦见上学 做梦梦到念书是什么意思 梦见上学代表什么意思预兆梦见上学,吉兆,生活会幸福快乐。梦见上学,可能是因为你近期的生活工作压力导致的&am…

ffmpeg如何在结尾添加帧_一种“视频帧对齐”的测试方案实践

点击蓝字?关注【测试先锋】,不再迷路!一起成为互联网测试精英,前瞻测试技术~导语全参考清晰度测算的时候,输入两个视频帧序列,但是视频帧序列没有对齐,怎么知道丢了哪帧?又怎么知道…

java mongo分组统计_探秘 Dubbo 的度量统计基础设施 - Dubbo Metrics

对服务进行实时监控,了解服务当前的运行指标和健康状态,是微服务体系中不可或缺的环节。Metrics 作为微服务的重要组件,为服务的监控提供了全面的数据基础。近日,Dubbo Metrics 发布了2.0.1版本,本文将为您探秘 Dubbo …

python可以做运动控制卡吗_今天,终于明白了运动控制器和运动控制卡的区别

原标题:今天,终于明白了运动控制器和运动控制卡的区别 运动控制器是完整的、独立的硬件平台,运动控制卡则需要一个载体(一个系统运行平台,必须基于PC)。 一、从安装使用方式来看 运动控制卡,一般是PCI插槽的&#xff0…

电子计算机技能竞赛数据,2015年浙江省中等职业学校计算机应用技术专业学生职业技能大赛“计算机检测维修与数据恢复”赛项规程.doc...

2015年浙江省中等职业学校计算机应用技术专业学生职业技能大赛“计算机检测维修与数据恢复”赛项规程.doc还剩8页未读,继续阅读下载文档到电脑,马上远离加班熬夜!亲,喜欢就下载吧,价低环保!内容要点&#x…

设备的dpr_湘潭污水处理设备_处理污水设备生产厂

湘潭污水处理设备_处理污水设备生产厂?氮磷过度排放导致水体富营养化仍是全球关注的水污染热点问题, 而对于传统城市污水处理厂来说, 污水的深度脱氮除磷和同步达标排放仍是需要攻克的难点问题.传统脱氮除磷工艺存在脱氮与除磷对有限碳源的竞争、硝化反应产物对厌氧释磷的抑制…

奥鹏大工17秋计算机文化基础,大工17秋《数字电路与系统》在线作业100分满分答案...

大工17秋《数字电路与系统》在线作业1一、单选题:1.实现与运算功能的逻辑器件称为( )。 (满分:5)A.与门B.或门C.非门D.与或门正确答案:——A——2.变量每增加一个,其函数卡诺图的小格数就增加( )倍。 (满分:5)A.0.5B.1C.1.5D.2正确答…

git 32位_编译64位的BorderlessGaming

BorderlessGaming确实是一款很好用的工具,我主要用来把AS的模拟器全屏,来把Surface当安卓平板用,但是这东西的官方Release和Steam版本都是32位的,不过好在它开源,那就自己动手魔改一份吧首先把源码clone到本地git clone https://github.com/Codeusa/Borderless-Gaming.git用VS打…