快手、孩子王、华为等专家分享大模型在电商运营、母婴消费、翻译等行业场景的实际应用 了解详情
写点什么

如何使用 DDD 方法验证业务规则

  • 2020-08-17
  • 本文字数:3236 字

    阅读完需:约 11 分钟

如何使用DDD方法验证业务规则

本文要点


  • 业务规则是系统拥有的特定领域知识的一个部分。

  • 合理构建的业务规则可以减少出错概率,并降低维护难度。

  • 不同业务规则的职责不同,例如提供验证或生成输出等。

  • 事件的处理方式决策会影响总体设计,并且在做出任何决策之前都需要了解其后果。

  • 应该围绕用户执行的任务来构造命令方法,并提供清晰的输出。


谈到业务规则,如果你是一名技术人员,可能首先想到的是代码行或业务规则引擎(如果你正在用的话)。但与编码相比,规则更接近知识管理的范畴。例如,建筑部门的员工了解许多关于卧室最小尺寸的规则,或者一片空间定义为卧室或书房的所需特征。如果一个人了解一个领域的规则,知道如何应用它们,就会成为这个领域的专家。我们的目标是创建模拟领域专家行为的软件应用程序。


在本文中,我将使用一个系统来管理公司的共享资源。这套系统的目标是帮助员工预订笔记本、投影仪、乒乓球桌等物品。


光是看上面一句话,你就可以立刻想出一串问题,比如:资源是什么?预订资源意味着什么?系统是否允许多次预订资源?诸如此类的问题应由领域专家回答,并将成为控制系统行为的业务规则。


这也将指导实体、值对象、命令和系统其他元素的定义。如何定义各个元素是更大的主题,超出了本文的范围。


也有专门针对这类主题的书籍,例如 Eric Evans 的《 领域驱动设计》;如果你在实现.NET,我建议你阅读《 使用.NET Core上手领域驱动设计》。


本文只会介绍如何构建业务规则这一部分,这些规则符合以下特征:


  1. 是一致的 。以任何开发人员都可以理解的方式组织规则对未来的更改是非常重要的。如果你认为系统总是在变化,而应用程序应该为这种变化做好准备,那么保持一致就是最佳选择。

  2. 很容易测试 。制定可测试的规则是确保更改不会破坏现有功能的唯一方法。

  3. 保持数据一致性 。保持数据一致是业务规则的主要职责之一。以我的个人经验来说,许多数据质量问题与系统规则处理不当有关。

  4. 很容易诊断 。我们应该努力避免任何意外的错误;但异常总是会发生的。如果你仅有的诊断信息说的是 对象引用为 null ,那么错误就非常严重了。


本文使用"输入-过程-输出"模型来表达系统规则。在这个模型中,一个输入被提供给系统;内部处理器接收输入并执行操作,从而创建输出。但是,在处理器开始执行任何操作之前,它必须验证所提供的信息是否有效。下一节将介绍如何处理这些验证。

模型细节


将命令发送到系统


使用基于域的方法处理验证的基本模型——这里显示了发送到系统的一条命令。


这个模型提供了在系统中处理业务规则的一个实现示例。这种方法基于领域驱动设计( DDD),但不用它而直接应用方法也是可以的。执行顺序如下:

1. 客户端发送一条命令

对于可以由客户端执行的建模命令,我们需要为其分配名称,从而识别它们。例如,它可以是 MakeReservation 之类的名字。注意,我们正在将这些设计定义移至软件设计和业务设计之间的一个中间点上。这听起来没什么特别的,但指定了名称之后,它可以帮助我们更有效地理解系统设计。这个想法是围绕任务而生的,与系统设计的 HCI(人机交互)概念有关。命令可帮助设计人员考虑系统需要支持的特定任务。


命令可能具有其他参数,例如日期、资源名称和用法说明。命令和查询责任隔离( CQRS)是一种使用命令对系统交互进行建模的模式。尽管在模型图解中客户端是一个用户,但它也可能是另一个系统。它还允许那些更改系统状态和仅返回数据的操作在系统的设计中具有不同的行为。



命令的语法验证

2. 语法规则验证

下一步是语法验证。根据 Merriam-Webster 所说,语法是将语言元素(例如单词)组合在一起以构成组分(例如短语或子句)的方式。在我们的上下文中,这意味着命令在领域的上下文中有意义。


这种验证可确保提供的数据对于系统而言是一致的。验证的一个示例是预订的开始日期——其值不应为过去的值,并且不能为 null。在验证阶段有多种返回错误的方法。Vladimir Khorikov 提供了一些有关 如何执行这些验证的示例。验证也可以在系统的不同层中进行。例如,最好在用户界面中通过验证确保提供的日期不是过去的,而不是在后端服务中发送这些值来做验证。这并不是说它也不能用在领域中;它可以防止其他客户端的滥用。



使用系统状态验证语义规则

3. 语义规则验证

语义验证取决于系统状态。此类规则旨在检查给定的命令在给定系统当前状态的情况下是否有意义,当前状态通常是通过系统实体存储和接收的。在 MakeReservation 命令之后,一种验证是检查是否有另一个客户保留了所请求的资源。这种验证也可以在客户端应用程序中进行;尽管如此,领域仍然有很多原因可以收到处理相同资源的预订请求。系统的责任是确保数据一致性。



处理更改系统状态的生产规则

4. 生产规则

生产规则是系统的核心。到目前为止,命令已经历了许多阶段,这些阶段可以确保系统能处理所提供的请求。生产规则指定了系统为达到所需状态而要执行的操作。它们处理的是客户试图完成的任务。它们使用 MakeReservation 命令作为参考,进行必要的更改以将请求的资源注册为保留资源。这些修改的结果是,实体和领域服务可以生成使客户端和其他系统知道更改已发生的事件。在我们一直使用的示例中,它将是 ResourceReserved。



事件的生成与处理

5. 事件

事件是一种与其他系统或子系统交互的通信机制。但是,在你的领域中实现它们之前,有必要确定系统对这些信号的反应方式。事件的处理有两种选项,各有其优缺点。


第一种是使用事务一致性。在这种模式中,系统使用同一事务来保持修改后的实体一致性。即使涉及多个汇总,事务也会跟踪更改并在流程结束时将其保存下来。这种模式称为工作单元。就代码生成而言,它提供了某些优势,例如简单性和效率。但有时它也是不切实际的。原因之一是它将修改后的实体保留在内存中,如果负载太大就会使用过多的内存和处理资源。另外,如果你在领域外通信,则将需要使用分布式事务,结果让应用程序更加复杂。


第二种选项是使用最终一致性。这将增强系统能力,因为你在执行命令时不会在内存中处理一个巨大的实体图。但这种选项会有其他后果。它意味着预订系统已完成其更改,并且如果其他子系统报告了故障,则预订系统必须运行一个补偿事务,还原先前的操作。这种方法还需要告知用户潜在的错误。选择某个选项时应权衡它们各自的优缺点、开发成本和所需的基础架构。例如,系统可能需要消息代理以同其他领域收发消息。



向客户端发送通知

6. 通知

命令完成后,系统必须将执行结果通知客户端。如果客户端是另一个系统,则可以省略此部分。但如果它是一个应用程序,我们可能需要通知用户命令的执行结果是成功还是失败,特别是在涉及异步处理时更需要这一步。继续讨论 MakeReservation 命令,其中一项要求是在分配特定资源之前需要所有者的批准。批准资源使用后,系统必须向用户发送确认信息。生成事件 ReservationApproved 时,模型中的通知开始运作。这个事件是另一条命令的结果,该命令应遵循我们之前描述的逻辑,但由不同的用户执行。


在设计中包含这一部分背后的想法是,除非获得批准,否则用户任务不会完成。同样,如果权限被拒绝,则领域可能需要还原部分更改。在设计系统时,我们必须考虑所有交互,直到用户的任务完成为止。

总结

业务规则是应用程序表达其对领域的了解的方式。正确构造业务规则有助于开发人员轻松理解代码,并应根据规则的职责将其分为不同类别。与此同时,使用结构化代码来表示用户任务可以减少开发团队需要理解的概念。因为业务规则取决于系统设计,所以解决方案架构师必须考虑设计支持它们的方式。


作者介绍:


Fabian Lopez 是佐治亚理工学院计算机科学硕士学位的软件工程师。目前,他在美洲开发银行担任解决方案架构师,设计烘焙行业的流程管理应用程序。Lopez 喜欢使用和创建软件模式,因为它为许多开发问题提供了解决方案参考。他定期参与用户研究,以识别用户模式并开发适合客户的解决方案。Lopez 注意到,许多好的技术解决方案失败了,因为用户在使用应用程序时陷入了迷茫,因而对解决方案的质量印象大减。


原文链接:


Using a DDD Approach for Validating Business Rules


2020-08-17 18:494837

评论

发布
暂无评论
发现更多内容

HttpClient 在vivo内销浏览器的高并发实践优化

vivo互联网技术

Java 高并发 HttpClient

CCF国际AIOps挑战赛

云桌派

Java 异步调用原理与实战

PPPHUANG

性能优化 线程池 Async Java core java nio

RT-Thread记录(八、理解 RT-Thread 内存管理)

矜辰所致

内存管理 RT-Thread 8月月更

如何利用CANN DVPP进行图片的等比例缩放?

华为云开发者联盟

人工智能 图像 昇腾AI

NFT服务平台如何选择——搭建NFT平台技术

开源直播系统源码

数字藏品 数字藏品软件开发 数字藏品系统软件开发 数字藏品交易平台开发

virtio 1.2 来了!龙蜥社区携手业界打造新版虚拟化 IO 标准

OpenAnolis小助手

开源 虚拟化 龙蜥技术 virtio

零门槛掌握基于大模型技术的AIGC场景应用

文心大模型

阿里云杨红军:应用管理——云上资源DevOps最佳实践

阿里云弹性计算

阿里云 DevOps 运维 应用管理 云上资源管理

一文讲透Java核心技术之高可扩展利器SPI

冰河

Java 程序员 架构师 spi 核心技术

SAP ABAP Netweaver 服务器的标准登录方式讲解

汪子熙

web开发 web服务器 abap Netweaver 8月月更

干货复盘 | 银行数智化转型十大趋势

易观分析

金融 银行 数智化转型

STM32入门开发 介绍IIC总线、读写AT24C02(EEPROM)(采用模拟时序)

DS小龙哥

8月月更

面试官:如何设计更好的分布式系统?

Java全栈架构师

程序员 架构 面试 分布式 后端

EasyNLP集成K-BERT算法,借助知识图谱实现更优Finetune

阿里云大数据AI技术

深度学习 阿里云 算法 开源技术 基础模型

Android进阶(十五)socket通信实现聊天室应用开发总结

No Silver Bullet

android 8月月更 开发总结

即日起,ONES 团队版50人以下免费

万事ONES

易周金融分析 :支付科技着力服务产业数字化升级

易观分析

金融 产业数字化 分析 支付科技

面试官偷偷告诉我:原来这样优化提升接口的性能

知识浅谈

API 优化 8月月更

PyTorch 与 TensorFlow 怎么选?

博文视点Broadview

Go 事,如何成为一个Gopher ,并在7天找到 Go 语言相关工作,第1篇

梦想橡皮擦

Python 爬虫 8月月更

开源一夏 | 如何使用Java操作华为对象存储OBS删除一个目录?

wljslmz

Java 开源 对象存储 华为云 8月月更

2篇论文入选KDD 2022!腾讯广告持续探索效果提升新思路

Geek_2d6073

SAP ABAP 关键字语法图和 ABAP 代码自动生成工具 Code Composer

汪子熙

Java SAP abap commerce 8月月更

科技赋能会展!3DCAT助力广东旅博会元宇宙场景的首次搭建

3DCAT实时渲染

云计算 元宇宙

首批成员!博云入选信通院“可信边缘计算推进计划”

BoCloud博云

云计算 开源 云原生

2022 CCF国际AIOps挑战赛决赛暨AIOps研讨会成功举办

BizSeer必示科技

人工智能 AIOPS

华贵保险连续五年获得“A级纳税信用企业”

江湖老铁

令人上头的AI论文(上) | IDP Inspiration

Baihai IDP

3 分钟看 3 个 JS 小把戏

掘金安东尼

JavaScript 前端 8月月更

2分钟一图看懂AntDB数据库产品

亚信AntDB数据库

AntDB 国产数据库 aisware antdb

如何使用DDD方法验证业务规则_研发效能_Fabian Lopez_InfoQ精选文章