对领域这个词的理解就是 DDD 入门的第一个难关。我们有时会被客户问到,领域到底是什么?首先要清晰地知道领域是什么,才能划分核心域、支撑域和通用域。换句话说,构成领域的要素是什么呢?
领域是一个非常抽象的词汇,我们需要先对其具象化。在英语的语境中,“Domain” 其实就是业务,指的是现实生活中的各种事务。处理税务、记账、售货记录等,这些都是领域。
于是,我们给领域下了一个定义:
领域(Domain)是业务相关知识的集合。
通俗来说,领域就是业务知识。业务有一些内在规则,存在专业性,比如财务、CRM、OA、电商等不同领域的业务规则不同。计算机只是业务规则的自动化。更加具体来说,构成领域的要素就是特定的业务场景。
通过对业务的场景划分,再对其分类,就是我们的子域。
核心域:那些对业务极其重要的场景,内容社区应用,就是提问、看帖、回复。
支撑域:那些对重要业务支持的场景,比如登录、找回密码等场景。
通用域:那些已经成为相对独立的支撑业务场景,比如实名验证、人机校验(以前是支撑,现在可以是通用)。
如果领域的构成要件是场景,上下文的构成要件是模型,那么领域和上下文之间就没有包含和被包含关系。
也不存在一个领域是否对应多个上下文的关系。
他们构成:上下文支撑领域的关系,领域导出上下文的关系。
DDD 软件建模就是业务问题和解决方案之间的桥梁。领域是问题,设计出来的模型是解的一部分。因此,问题和解形如 x 和 f(x) 的关系,f = 软件建模过程。
举个例子来说,某个电商网站有多个渠道,零售、批发、企业采购等多个场景的业务,这是他们的领域。对于研发工程师来说,他们会最终设计出订单、商品等模型上下文,来支持这些领域。
聚合被赋予了两个责任:
而其持久化是一个老大难问题。
关于业务的一致性,Eric DDD 给我们描述了一种理想情景。只要把业务一致的一组模型从数据库中统一获取到,对其做业务修改,然后再持久化回去,就可以避免业务的一致性被破坏。
业务的一致性可以这样理解。我们有订单和订单项,订单的总价由订单项计算得来。如果不长眼的程序员把订单项直接修改了,而不更新订单,就会带来 bug。
但是,遗憾的是我们的内存不是无限大,而且数据会在断电后丢失。我们必须把数据从磁盘中读取出来,而磁盘的访问速度很慢。数据在磁盘中的组织形式使用了集合+关联的方式存放,这是由于我们为了降低数据冗余和方便查询而不得已为之。这就是关系模型和对象模型的差异,而不得不采用一些技术方法转换(ORM)。
而数据的整体存储,让聚合的持久化变得困难和性能低下。
一个简单的道理是,我们只需要一个橘子,却总想把橘子树搬来搬去,虽然摘橘子需要通过橘子树。
充血模型已经是很多 DDD 实践者的潜在认知,简单来说就是把业务行为放到模型中。
这种做法看似满足了面向对象的实践,但是在实际工作中,它并不方便,甚至有些别扭。在培训中,有学员找我们说,学了 DDD 之后不会写代码了,甚至忘记之前的代码该如何编写。
极端一点的例子,还会有人在聚合根中调用仓储来实现聚合的存储。这时,他们发现矛盾在于 JPA 的存储需要使用实体的类型信息,这时候便束手无策了。
在辩证唯物主义认识论中,一个行为构成的要件是:主体 + 动词 + 客体。
在英语学习中,主谓宾结构的主体是主语,客体就是宾语。甚至,主系表结构也满足这个道理。主语是主体,表语是主体的属性,也是客体。
“太阳是圆的”。指的是,太阳的形状是圆的。太阳是主体,“是” 作为逻辑谓词可以认为是动词,“圆的”是太阳的外观属性。
合适的充血模型是给 “主体”充血,给客体贫血。特殊的情况是,当一个模型操作它的属性的时候,它也可以是主体。因此,给领域模型的操作能力,应该仅限于操作自己的属性。而领域模型的构建、业务处理、持久化应该交给主体来做。
一个有意思的悖论就是,不合适的充血模型就像让一张桌子让它自己把自己搬到楼上去,我们难描述这种行为。更好的做法不是去找一个搬运工去搬这个桌子么,这次行为的主体就是搬运工,客体就是这个桌子。
分层有两个原则:
分层的目的为了隔离差异,没有差异而进行的分层就是浪费。由于差异的出现,每层所对应的客体就发生了变化。
多对多就是客体的含混不清,迷失了中间模型。
一个订单可以有多个商品,实际上是一个订单有多个订单项。
辨明客体,可以让代码变得清晰、简单、解耦。在现实中,一个老板可以有多个公司,一个公司也可以由多个老板投资。他们之间的多对多关系是通过 “股东” 这个客体来承载的。
在有限责任的公司中,股东身份和老板的个人身份(自然人)相互独立,并得到司法支持。
原网址: 访问
创建于: 2022-08-08 09:16:06
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论