本文书接上回《为了给Javaer落地DDD,我们不得不写开源组件》,欢迎关注公众号(老肖想当外语大佬),获取最新文章更新和DDD框架源码,视频和直播在B站。
 

背景

我们在《这是DDD建模最难的部分(其实很简单)》一文中介绍了一个关于“用户-角色”的建模过程,当我们讨论“如何分析业务和建模,以在满足需求的前提下,使得需求和模型的边界都清晰且一致”这一话题时,发现很多经验丰富的开发者,总会带着各种各样的顾虑和疑惑,“数据库里的表关系怎么处理”,“关联查询不就解决问题了吗?”,“为啥不能关联查询?”,“既然有了某某Id,说明它们有关系啊,你为啥说边界明确?”。
我就在想,这里的问题到底在哪里,为什么我们觉得理所当然的想法,仍然有很多人会觉得困惑,经过和我们团队伙伴们深入探讨,我觉得我们找到了问题所在。

知识的诅咒

我记得在《倚天屠龙记》中有这么一幕,张三丰现场传授张无忌太极剑法,教完之后,问张无忌好几遍:“还记得多少?”,张无忌最后说:“我已经把所有的全忘记了!”,张三丰很高兴:“好,你可以上了。”
回到我们软件设计的场景,我们经验丰富的工程师,总是会深思熟虑,会考虑性能够不够?模型怎么存到表里?表结构是否合理?这里应该一对一关系还是一对多?又或者应该是多对多?这一系列的问题使得大家无法集中精力思考业务的本质是什么,过早地把注意力放在了技术上,在跟业务专家热烈沟通客户场景的时候,你的脑海里却满满的SQL语句怎么写。
我想,这大概就是知识的诅咒吧,背负着沉重的心智负担,大概率也做不出更准确的判断。

忘掉数据库

现在假设科技已经发展到了非常顶级的水准,我们具备了如下能力:
  1. 应用程序的内存无限大;
  2. 应用程序内存永远不会丢失;
 
那么,我们还需要数据库吗?我想,应该不需要了,我们代码会是怎么样的?是不是在内存中构造出模型的实例添加到它的集合容器中,就可以了?
假如不再需要数据库了,你建模的时候是不是可以忘掉数据库,把模型看作是一个个独立的类型实例即可?你的建模思路是否会发生一些变化?那么在这个背景下,我们重新审视“领域的边界”这个概念。
假如我们仍然使用之前的文章中提到的准则:“聚合之间不存在相互引用”,那么你设计出来的结果是不是就会像我们之前推演的那样,像下图一样:

如果你仍然有疑惑,我把具体的类图也添加进来,你是不是就一目了然了:

 

回到现实

当然,现实是我们的科技并没有像上面设想的那样发达,我们最终还是要将模型数据存储到数据库的,因此,我们需要ORM框架来帮助我们解决模型的“存取”问题,注意这里我用到的是“存取”,不包含搜索,搜索的事情,我们可以用更加灵活的解决方案,这涉及到一种叫做CQRS的模式,这又是另一个故事了。
假如我们有一个很强大的ORM,可以帮助我们根据Id,取出模型,我们操作完模型,ORM再帮我们“Save”进数据库,我们不需要关心这里面它到底做了什么,那么是不是这个ORM也可以帮助我们摆脱“数据库知识”的诅咒,让我们在建模的时候专注需求和模型?
 

结论是什么

基于上面的推导,我认为有如下结论:
  1. 数据库知识,会成为分析需求和建模时候的心智负担;
  2. 一个功能强大的ORM,有利于帮助工程师摆脱“数据库知识”的心智负担;
  3. 分析需求的时候,只需要关心需求和模型即可;
 
那么,你对上面的结论有什么看法?你在用什么样的ORM?你参与的项目的代码组织方式,是否让你可以专注业务?欢迎在文章评论区友善地讨论,也欢迎关注我的公众号(老肖想当外语大佬)以获得最新的更新。

后续

下一篇,我将介绍一种能够在各个角色间建立共鸣的建模沟通方法,以使得我们的建模思维可以落地和复制,敬请期待。

这就是为什么你学不会DDD的更多相关文章

  1. Lind.DDD敏捷领域驱动框架~Lind.DDD各层介绍

    回到目录 Lind.DDD项目主要面向敏捷,快速开发,领域驱动等,对于它的分层也是能合并的合并,比之前大叔的框架分层更粗糙一些,或者说更大胆一些,在开发人员使用上,可能会感觉更方便了,更益使用了,这就 ...

  2. DDD 理解

    DDD提倡充血模型,业务放在类中,而不是服务中,刚开始是比较不清楚的.突然明白,以前开发桌面程序的时候,不就是这样处理了吗?业务分析和代码实现一一对应.因为桌面程序没有数据库,他就是纯粹的面向对象的实 ...

  3. DDD CQRS架构和传统架构的优缺点比较

    明天就是大年三十了,今天在家有空,想集中整理一下CQRS架构的特点以及相比传统架构的优缺点分析.先提前祝大家猴年新春快乐.万事如意.身体健康! 最近几年,在DDD的领域,我们经常会看到CQRS架构的概 ...

  4. DDD 领域驱动设计-看我如何应对业务需求变化,愚蠢的应对?

    写在前面 阅读目录: 具体业务场景 业务需求变化 "愚蠢"的应对 消息列表实现 消息详情页实现 消息发送.回复.销毁等实现 回到原点的一些思考 业务需求变化,领域模型变化了吗? 对 ...

  5. DDD初学指南

    去年就打算总结一下,结果新换的工作特别忙,就迟迟没有认真动手.主要内容是很多初学DDD甚至于学习很长时间的同学没有弄明白DDD是什么,适合什么情况.这世界上没有银弹,抛开了适合的场景孤立的去研究DDD ...

  6. 初探领域驱动设计(2)Repository在DDD中的应用

    概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...

  7. 一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?

    写在前面 阅读目录: 问题根源是什么? <领域驱动设计-软件核心复杂性应对之道>分层概念 Repository(仓储)职责所在? Domain Model(领域模型)重新设计 Domain ...

  8. Redis学习笔记~Redis事务机制与Lind.DDD.Repositories.Redis事务机制的实现

    回到目录 Redis本身支持事务,这就是SQL数据库有Transaction一样,而Redis的驱动也支持事务,这在ServiceStack.Redis就有所体现,它也是目前最受业界认可的Redis ...

  9. Lind.DDD.RedisClient~对StackExchange.Redis调用者的封装及多路复用技术

    回到目录 两雄争霸 使用StackExchange.Redis的原因是因为它开源,免费,而对于商业化的ServiceStack.Redis,它将一步步被前者取代,开源将是一种趋势,商业化也值得被我们尊 ...

  10. [转]DDD领域驱动设计基本理论知识总结

    领域驱动设计之领域模型 加一个导航,关于如何设计聚合的详细思考,见这篇文章. 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity i ...

随机推荐

  1. 博客正式更换为emlog

    Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 博客正式更换为emlog 日期:2017-4-2 阿珏 谈 ...

  2. Vue聊天框自动滚动底部

    原理:通过监听数据更新,将滚动的最大高度赋值给滚动条的最大高度,并等待页面更新完成后再将页面滚动到底部. 容器代码 watch监听 scrollTop: 距离最顶部高度 scrollHeight:滚动 ...

  3. 使用GET方法访问网站

    使用GET方法访问网站 服务器接收get参数 server.py import flask app = flask.Flask(__name__) @app.route('/') def index( ...

  4. 小米便签AS部署之Git的基本使用

    1 项目测试截图 及仓库地址 https://gitee.com/magicfatblink/Notes-master 2 小米便签代码的移植 2.1 IDE 的准备 2.1.1 AS版本选择 由于小 ...

  5. mysql多表删除指定记录

    在Mysql4.0之后,mysql开始支持跨表delete. Mysql可以在一个sql语句中同时删除多表记录,也可以根据多个表之间的关系来删除某一个表中的记录. 假定我们有两张表:Product表和 ...

  6. Linux 中 uid、gid、euid、egid、groups 之间的关系

    导航 1 权限匹配流程 2 五种身份变化 3 有效用户/组 4 特权对 Shell 脚本无效 5 Sudo 与 SUID/SGID 的优先级 6 SUID.SGID.Sticky 各自的功能 Linu ...

  7. VBA-合并多个工作簿

    '合并多个工作薄,并以工作薄的名字给sheet表命名(每个工作薄只有一张表) Sub test() Dim str As String Dim wb As Workbook str = Dir(&qu ...

  8. 算法金 | 一个强大的算法模型,GPR !!

    大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 抱个拳,送个礼 高斯过程回归(GPR)是一种非参数化的贝叶斯方法,用于解决回归问题.与 ...

  9. c 语言学习第五天

    break 语句 在循环体中使用 break,可以跳出循环 打印 10 以内的数. #include<stdio.h> int main(){ int i,j = 20; for(i = ...

  10. SwiftUI学习01-基本使用

    SwiftUI 是苹果推出的一种现代化方式,用于创建跨所有 Apple 平台的用户界面.它通过声明性语法简化了 UI 的开发流程.下面是一个基本的 SwiftUI 示例,展示了如何使用 SwiftUI ...