DDD学习笔记四

news2024/11/18 4:51:19

领域模型的构建

  • 基础领域模型的基本组成有名称、属性、关联、职责、事件和异常

  • 发掘领域概念3种策略:
    1)学习已有系统,重用已有模型
    2)使用分类标签。分类标签来源于领域,需要我们研究一些资料并做一些提炼。从采用5W法开始,即事件(What)、原因(Why)、地点(Where)、时间(When)、人员(Who),之后在其上加以补充
    3)识别名词短语。
    一般情况下,我们会从策略1开始,组织中完全没有之前相关的旧系统的情况并不多见,之后策略2和3结合使用

  • 概念类命名的注意事项如下:
    使用领域术语。记住,模型的首要任务是沟通,使用领域专家熟悉和习惯的名字,即使你认为有更精确的表达方式。
    对于相同的名称但不同场景的情况,应该将最易于识别的名字留给最常用的类型,比如“订单”可以在支付场景和配送场景中使用,
    应该 把它用在支付环节而不是配送环节,因为支付环节更加的核心,更符合这个名字的本身的含义,业务逻辑也更复杂。
    尽量避免使用编程语言中的保留字,比如“集合”。
    不要凭空创造概念或添加前缀和后缀来区分名称,这只会增加沟通的障碍。始终以领域专家和系统用户喜欢的方式进行沟通,
    这是DDD的内在特殊要求

  • 创建关联
    阅读导向箭头“►”是可选的,它指示关联名称阅读的方向,并不表示可见性或导航的方向
    关联表示为类之间的连线,关联的末端可以包含多重性
    采用“主谓宾”结构为关联命名,连接线上只显示谓语
    关联符号包含“0”时,不管是“”“0…”,还是“0…1”都客观上意味着这是一种可选关联,并不一定发生
    关联类允许将关联本身作为类,并且使用属性、操作和其他特性对其进行建模。
    在这里插入图片描述
    在这里插入图片描述

  • 使用关联类标准
    1)通用语言中就有关联类的概念,如×××合同,用来约束两个模型之间的关系。
    2)模型的某些属性与关联相关,这些属性脱离关联将显得无意义。
    3)关联类的实例具有依赖于关联的生命周期,如合同期、项目时长等。
    4)两个模型之间有多对多关联,并且存在与关联本身相关的信息。
    其中第3条特征明显,可作为一个常用的标准。

  • 关联简化
    1)限制关联数量
    2)限制关联方向
    3)使用限定关联

  • 定义属性
    当领域模型需要记住信息时,引入属性,
    属性的3种类:基本类型、通用的值对象和项目中的其他业务对象(前两种类型一般写在类图框中,而第三种使用关联来表达)
    在这里插入图片描述

  • 使用方法:
    该操作的访问速度较慢。为了避免线程阻塞,甚至需要考虑为该操作提供一个异步版本,那么将其建模为属性就可能导致开销过大。
    特别是那些访问网络或文件系统的操作,更应该使用方法而非属性。
    该操作是一个转换操作,如toString()方法。
    该操作每次返回的值不同,即使传入的参数不变。比如,Guid().NewGuid()方法每次都返回不同的值。
    该操作有严重的、能观察到的副作用,比如抛出异常。
    该操作返回一个集合。返回集合的属性容易误导用户,比如,Employees和Addresses等属性就是不合适的。
    需要指定参数才能访问的属性,如前面多个地址的例子。
    除以上情况外,请尽量使用属性。

  • 使用属性建模时,还有一些细节值得注意:
    1)如果不想让调用方改变属性的值,要创建只读属性。
    2)不要提供只写属性,也不要让设置方法的存取范围比获取方法更广。如果一个属性值没有获取的意义,比如配置资源地址,此时应该提供set方法而不是属性。
    3)要为所有属性提供默认值。技术上默认值不会导致异常或安全漏洞,业务上也往往体现一定的“默认”的领域含义
    4)要允许用户以任意顺序来设定属性的值
    5)如果属性设置方法抛出异常,则要保留属性原来的值。这在业务上也是合理的。
    6)不要在属性获取方法中抛出任何异常,这会令人感到困惑。如果确实存在这种可能性,请改用方法

  • 分配职责
    业务职责则由其方法来定义

-模型层但职责:分配策略-信息专家模式
在信息专家模式中,职责分配给了具有完成该职责所需信息的模型。信息包括模型的各种成员,如字段、属性、关联,以及对资源的可见性等。
如果一个对象能够承担相应的职责,那么最好不要让更大的、具有更多信息的对象来承担这些职责
领域逻辑不要与技术架构混为一谈,领域逻辑要与任何持久化机制解耦

  • 创建领域服务完成职责
    如果一个职责需要的信息无法由一个模型提供,应该怎么处理?可以分为以下两种情况:
    1)增加关联以获取必要的信息。
    2)使用领域服务。
    当一个职责发现采用信息专家模式没有找到合适的模型时,需考虑创建一个领域服务模型是否更好

  • 方法是职责和操作的实现,方法参数设计的注意事项如下
    1)应使用类层次中最接近基类的类型来作为方法参数,并保证该类型能够提供成员所需信息。这样做可以使得方法的适用范围更广,因为子类能取代任何基类的位置,即子类可以传入以基类定义的参数,但反过来则不行
    2)不要将指针、指针数组和多维数组作为方法的参数。即使不在DDD团队中,且代码要保证优秀可读性的场合,指针和多维数组也是难以应对的。可以对方法进行重新设计以避免使用这些类型作为参数。
    3)尽量不使用输出参数,如out、ref关键字修饰的参数。这会增加代码的复杂性,给领域模型的验证和测试带来干扰。同理,尽量使用值对象而不是实体类型的参数,因为值对象没有状态,传入的是一个副本。
    4)可以使用重载(Overload)机制来简化方法的命名。重载即模型拥有很多同名的方法,但它们的参数不同,根据传入的参数匹配对应的方法。不要增加无谓的名称,以减少沟通的难度。使用重载机制让方法的命名更加顺畅。

  • 触发事件

  • 领域事件是一个特殊的模型成员。领域模型状态的改变(属性)或者执行操作时达到某些判定条件,都可能触发事件
    (1)事件的捕获
    领域事件是领域专家所关心的发生在领域中的有影响力的事件。将领域中发生的活动建模为一系列离散事件,每个事件都用领域对象来表示,领域事件是领域模型的组成部分,用于表示领域中所发生的事。
    定义有两个层面:一是纯业务层面,领域事件来源于领域专家的通用语言,具有业务含义;二是设计层面,领域事件可以建模为一个领域对象,但这种对象是一种不可变类,也就是值对象,它将成为其他领域对象的一部分
    事件的命名是过去时态,事件的载体为类图,其中包含的属性称为事件参数,它们是该事件消费者需要的关于事件的信息
    在这里插入图片描述

  • 领域事件的3个本质:
    操作因果关系的体现。
    为未来处理逻辑留下的逻辑占位符。
    提供操作的异步性。

  • 领域事件的作用。
    保证模型间的数据一致性。
    替换批处理操作。
    系统集成。
    在这里插入图片描述

  • 处理异常
    异常是一种特殊的意外情况处理机制
    异常处理是领域模型要考虑的一部分,原因在于模型的责任不可能无限大。在遇到自己处理能力之外的情况时,要采用异常机制报告错误,并将处理权转交。异常就是这样一种机制,某种程度上,它可以保证领域模型的纯洁性,让其只关注于核心逻辑,而不用包含一堆意外情况处理代码

  • 自定义异常的注意点:
    要避免太深的继承层次,一般Exception类即可满足要求。
    一定要以Exception作为后缀。
    要使异常可序列化。为了使异常能够跨应用程序和跨远程边界工作,这样做是必须的。
    要提供以下常用的构造函数。
    在这里插入图片描述
    要把与安全性有关的信息保存在私有的异常中,确保只有可信赖的代码才能得到该信息。比如数据库连接抛出的各类异常,可能会泄露你的表命名、表结构等信息。
    可以为异常定义属性,这样就能从程序中取得与异常有关的额外信息。

  • 抛出异常的注意点如下:
    在领域模型中,要使用异常来处理意外情况而不是错误码。
    不要在能处理的正常流程中抛出异常。
    要为所有的自定义异常构建一份文档,使开发人员能够掌握,让他们能使用最合理、最具针对性的异常,比如不要使用“集合超容”来描述“购物车已满”。
    在异常消息中避免使用感叹号和问号。
    注意异常消息的本地化。

除了异常本身的类图,也可以在相关领域模型中列出可能抛出的异常
在这里插入图片描述

典型的领域逻辑建模

  • 领域逻辑主要包括规则与约束、流程与分支、验证与筛选、算法与计算、时间与空间、有状态与无状态、同步与异步等
    在模型中,使用大括号{}来标记规则
    在这里插入图片描述

  • 规则与约束

    当规则和判断条件众多时,把这个约束提取到一个单独的方法中,并用具有业务含义的名称来对其命名

    约束既可以放在模型内部,又可以单独将其提炼出来作为策略类或领域服务
    需要单独提炼的验证规则的特点:
    验证约束所需的信息并不属于这个对象。
    相关规则在多个对象中出现,造成了代码重复,违反了“一处一个事实”原则。
    很多领域逻辑是围绕这些约束展开的,它的层级不适合下放到实体或值对象的方法中。将约束单独作为一个模型,可以避免重要的领域概念被淹没,使通用语言更加顺畅

  • 流程与分支

业务流程建模对应的是UML中的活动图
在这里插入图片描述
活动图对应的是协作图或时序图而不可能是类图,它们展示了一个用例的参与对象,以及对象之间传递的消息
在这里插入图片描述
,协作图中的节点已经变成了各个领域模型,其中的逻辑分支用中括号[]来标记,如图5-32中的[支付成功]。在业务流程图的基础上映射绘制出来的协作图,不仅能交流业务,还能直接指导实现开发,是对流程与分支建模的最理想模型。

  • 验证与筛选
    规格模式是将一组判断条件封装成一个单独的值对象,名称中一般带有形容词,表达了很强的领域含义,代表客户对于程度的看法,如“大额存单”“过期发票”“优秀成绩”等。如图5-34所示,这个值对象会有一个是否满足的判断方法(一般是IsSatisfiedBy()函数),用于校验某个对象是否满足该规格所表达的条件,只返回真假校验。多个规格对象还可以灵活组装,生成新的规格对象。
    在这里插入图片描述
    在业务逻辑上,规格与约束的不同点在于,约束是必须满足的,而规格只是从集合中筛选或验证符合条件的成员
    规格的用法主要有以下3种:
    1)验证对象,检查它是否满足某些条件。
    2)筛选符合条件的对象。
    3)创建满足某种条件的新对象

  • 算法与计算
    算法逻辑涉及领域的核心逻辑,其本身往往是内聚的,将其独立出来是最值得倡导的建模实践,如复杂的候选人排名规则、销售佣金的计算策略、保单的风险评估等。算法逻辑独立出来后,避免了复杂算法对领域模型的干扰,领域中的其他模型就可以专注于表达“做什么”的逻辑,而把“如何做”的复杂细节转移给了算法模型
    领域中的算法可以建模为算法对象,常见于实时系统、科学和工程领域中。如果算法需要的信息都在实体或值对象内部,可以将该算法建模为该对象的操作。但如果该算法内聚且明显独立于领域对象而变化,那就不适合绑定一个领域对象,要显式地将其建模为算法对象,而不是隐藏在模型和代码深处。算法对象声明关键字是<>,标记在类图或协作图上以表明身份
    算法对象经常会封装计算其算法所需要的数据,这些数据可以是初始化数据、中间结果或阈值数据。算法对象的主要职责是执行算法,不要把任何业务协调职责放入其中
    在这里插入图片描述
    将算法封装为领域服务是最佳选项,尤其是涉及多个实体类型、返回值为值对象的计算时。
    将领域计算逻辑单独建模而不放在其他业务对象内的优点如下:
    1)不给领域模型增加负担。如果计算所需的信息超出了该对象的范围,又会增加不必要的耦合。
    2)关于计算逻辑的领域概念变得更加清晰,单独的计算规则一般都是核心域范畴,单独出来可以增加通用语言的词汇。
    建模为操作符重载
    操作符重载就是让领域模型可以像基本类型那样进行加(+)、减(-)、乘(*)、除(/)操作,还包括等于(==)、大于(>)、小于(<)等比较操作
    当一个类内部出现public static的方法时,应该考虑该方法是继续放在这个类中还是单独成领域服务

  • 时间与空间
    定时约束建模通常遵循以下策略:
    1)对于交互中的每条消息,考虑其开始时间和触发周期。将这个实时特征建模为消息的定时约束。
    2)对于交互中每个值得关注的消息序列,考虑是否有一个相关的最大的相对时间。将这个实时特征加为对该消息的定时约束。
    把系统对时间的要求表示为约束{},并放在对应的消息旁边即可。时间是动态逻辑,只能展示在时序图或协作图上。
    在这里插入图片描述
    计时器对象是由外部计时器激活的控制对象。计时器对象要么自己执行某个动作,要么激活另一个对象来执行期望的动作
    计时器属于应用服务而不是领域服务
    在这里插入图片描述

  • 时效建模 : 时效是指与时间段相关联的信息
    建模的方式是维护与一组时间间隔相关的信息,而不是单个值
    在这里插入图片描述

  • 建模空间指模型在分布式系统中的位置
    在这里插入图片描述

  • 有状态与无状态
    建模为独立模型的状态:
    领域模型具有多个状态,它们会根据一定条件进行转换。
    不同的状态会导致不同的行为。
    未来还可能会增加新的状态。
    最佳方法是对这些状态建模,而不只是用条件语句加以判断

  • 同步与异步

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

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

相关文章

解决 prettier/prettier 和 indent 冲突问题和一点简单思考

用过 prettier 的都知道&#xff0c;经常会遇到 prettier 与 eslint 的某些规则冲突的情况。在之前的一篇文章中&#xff0c;我简单地描述过怎么搭建起应用 eslint/prettier 的基本配置&#xff0c;也提到了怎么解决 prettier 与 eslint 的一些冲突问题。 其中有这么一段话&am…

C语言 | Leetcode C语言题解之第202题快乐数

题目&#xff1a; 题解&#xff1a; //计算的过程函数&#xff0c;我没重点讲&#xff0c;很简单看一下代码就好了 int getSum(int n) {int sum 0;while (n) {sum (n % 10) * (n % 10);n / 10;}return sum; }bool isHappy(int n){int sum getSum(n);int hash[820] {0};whi…

寒武纪实现高维向量的softmax进阶优化和库函数对比

关于寒武纪编程可以参考本人之前的文章添加链接描述,添加链接描述,添加链接描述 实验证明,axis=0和axis=-1的时候,手写softmax速度可以和库函数媲美,甚至于更甚一筹。 src/softmax.mlu #include <bang.h> #include

OPCUA相关概念和KepServer OPCUA连接PLC

文章背景 项目中需要使用OPC UA 来读取PLC的点位。本文简单介绍了OPC UA和使用KepServer软件连接PLC并读点。OPC相关概念 OPC之前&#xff0c;软件开发需要写大量驱动程序去连接设备&#xff0c;设备上的一个硬件改变&#xff0c;应用程序都有可能需要重写&#xff0c;不同设备…

Facebook助力中东地区博弈游戏广告营销新视界

Facebook助力中东地区博弈游戏广告营销新视界 中东地区&#xff0c;作为世界上充满活力和潜力的游戏市场之一&#xff0c;近年来&#xff0c;Slots游戏在该地区的热度持续攀升。众多游戏开发商和广告主纷纷寻求有效的推广方式&#xff0c;以吸引更多的潜在用户。在这个过程中&…

在自定义数据集上对 YOLOv10 模型进行微调以检测肾结石

对 YOLOv10 模型进行微调以增强肾结石检测,可将诊断时间从每份报告 15-25 分钟显著缩短至每秒处理约 150 份报告。这项研究面向医学研究人员、医疗保健专业人士和 AI 公司,通过以数据为中心的技术,无需改变模型架构,即可获得94.1 的 mAP50 。 NMS 免费培训:它真的有效吗?…

11083 旅游背包(优先做)

这个问题可以使用动态规划来解决。我们可以定义一个三维数组dp&#xff0c;其中dp[i][j][k]表示前i种物品&#xff0c;总体积不超过j&#xff0c;总重量不超过k的最大价值。 我们可以使用四重循环来填充这个数组。外层循环遍历所有的物品&#xff0c;第二层循环遍历所有可能的…

C++视觉开发 一.OpenCV环境配置

一.OpenCV安装环境配置 1.OpenCV安装 &#xff08;1&#xff09;下载 官方下载链接&#xff1a;http://opencv.org/releases 这边选择需要的版本&#xff0c;我是在windows下的4.9.0。&#xff08;科学上网下载很快&#xff0c;否则可能会有点慢&#xff09; (2)安装 双击下…

卢森堡-海外媒体发稿:新闻媒体宣发报道超给力

卢森堡高卢期刊gauljournal 卢森堡高卢期刊gauljournal自成立以来&#xff0c;一直致力于报道真实、客观的新闻&#xff0c;为读者提供最全面、准确的信息。多年来&#xff0c;该期刊在海内外媒体宣发方面取得了极大的成就&#xff0c;其报道在国际媒体上的曝光率非常高&#…

20240701每日后端------------java启动JVM参数配置说明Parameters -D, -X, -XX

主题 JVM有很多参数&#xff0c;当我们通过命令行启动Java程序时&#xff08;例如&#xff0c; java -jar app.jar&#xff09; 我们经常指定各种参数选项。很多人对为什么有时我们使用 -D &#xff0c;有时我们使用 -X &#xff0c;偶尔我们使用 -XX 感到困惑。 名词解释 …

短剧挂载推广教程,短剧项目怎么分销推广?如何入驻平台当推广达人?达人推广的方式是怎么样的

目录 一、短剧怎么做&#xff1f; 二、在哪找资源挂?怎么挂? 1、在哪找资源挂? 2、怎么挂? 三、有哪些短剧看剧平台或者分销平台? 1&#xff1a;短剧看剧小程序怎么入驻当达人? 2&#xff1a;短剧cps分销小程序怎么入驻当达人? 一、短剧怎么做&#xff1f; 想要当…

Linux常用工具使用方式

目录 常用工具&#xff1a; 安装包管理工具&#xff1a; 查找含有关键字的软件包 安装软件 安装文件传输工具 安装编辑器 C语言编译器 C编译器 安装调试器 安装项目版本管理工具 cmake 卸载软件 安装jsoncpp 安装boost库 安装mariadb 安装tree&#xff08;让目录…

多语言跨境商城系统怎么选择

随着全球化的推进和电子商务的蓬勃发展&#xff0c;跨境电商已经成为了一个不可忽视的商机。不同国家和地区的语言和文化差异给跨境电商带来了一定的挑战。为了顺利运营跨境电商平台&#xff0c;选择一款适合的多语言跨境商城系统至关重要。但在众多系统中选择合适的一款&#…

探讨DC/AC电源模块为绿色能源应用提供可靠的转换解决方案

BOSHIDA 探讨DC/AC电源模块为绿色能源应用提供可靠的转换解决方案 DC/AC电源模块是一种能够将直流电源转换为交流电源的装置。随着绿色能源的不断发展和应用&#xff0c;DC/AC电源模块在可再生能源、电动车辆、太阳能发电等领域中扮演着重要的角色。本文将着重探讨DC/AC电源模…

3DMAX折纸插件FoldPoly使用方法详解

3DMAX折纸插件FoldPoly使用教程 3DMAX折纸插件FoldPoly&#xff0c;用于挤出可编辑多边形的边&#xff08;边界&#xff09;并可旋转&#xff08;折叠&#xff09;新生成的面&#xff0c;创建类似手工折纸以及纸箱包装盒的建模效果。 【版本要求】 3dMax2014 - 2025&#xff…

2024最新!将mysql的数据导入到Solr

Solr导入mysql的数据 如何安装导入数据前准备配置Solr的Jar包以及Mysql驱动包1.1、将solr-8.11.3\dist下的两个包进行移动1.2、将mysql-connect包也移动到该位置1.3、重启Solr项目 配置xml2.1、第一步我们需要创建核心2.2、第二步修改xml(这里是结合19年的教程)2.3、 创建data-…

Soul社交元宇宙智能连接安全相伴,打造值得用户信赖的社交环境

随着人工智能技术的快速发展,社交平台正在迎来一场革命性的变革。从智能推荐到情感分析,社交平台通过深度学习和数据分析为用户提供更加个性化、智能化的社交体验。与此同时,数字时代人们的安全意识正逐渐增强。为此,一个智能、安全的社交平台成为人们迫切需要。而新型社交平台…

Baidu Comate专业版90天免费试用,上班摸鱼好帮手

Baidu Comate专业版&#xff0c;扫描图中二维码或者点击链接下载安装&#xff0c;即可获得Baidu Comate专业版90天免费试用&#xff0c;支持idea、vscode、eclispe。它结合了百度大数据和文心大模型&#xff0c;为开发者们提供了更智能、更高效的编程体验&#xff0c;上班摸鱼好…

教师备课三要素是指什么内容

在教育的舞台上&#xff0c;教师的角色至关重要。他们不仅是知识的传递者&#xff0c;更是学生学习路上的引导者。那么&#xff0c;教师备课的三要素究竟是什么呢&#xff1f;这不仅是每个教师在教学过程中必须面对的问题&#xff0c;也是他们不断探索和实践的课题。 教师备课的…

layui+jsp项目中实现table单元格嵌入下拉选择框功能,下拉选择框可手动输入内容或选择默认值,修改后数据正常回显。

需求 table列表中的数据实现下拉框修改数据&#xff0c;当默认的下拉框不符合要求时&#xff0c;可手动输入内容保存。内容修改后表格显示修改后的值同时表格不刷新。 实现 layui框架下拉框组件只能选择存在的数据&#xff0c;不支持将输入的内容显示在input中的功能&#x…