F#奇妙游(25):ADT和领域设计

前言

采用ADT来对领域进行设计,是一种很好的实践。在这种实践中,我们可以把领域中的数据抽象成ADT,把领域中的操作抽象成函数,然后利用ADT的类型系统来进行类型检查,从而保证领域中的数据和操作的正确性。

设计目标

首先,我们的设计目标如下:

  1. 各领域专家架和程序开发都能够理解的设计
  2. 能够利用ADT的类型系统来进行类型检查
  3. 不需要与具体的编程语言乃至编程范式绑定

设计原则

那么我们需要遵循大概以下的原则:

  1. 描述ADT的术语应该尽量与领域中的术语一致
  2. 描述ADT的数据结构应该尽量与领域中的数据结构一致
  3. 描述ADT的操作应该尽量与领域中的操作一致
  4. ADT的分析应该专注于组合而不是继承
  5. ADT的各个组合部分都应该都领域含义,而非编程语言的实现细节
  6. 编程实现的细节(例如基本数据类型、数据结构和算法的实现)在设计阶段应该被忽略

软件开发流程

从本质上来看,所有的设计都应该是迭代的。不过我们还是可以首先给出一个线性的流程,然后再给出检查点,并定义迭代的流程。

首先是整个软件系统开发的流程,如果我们非常丧心病狂,并且非常注重完备性,务必要把所有的步骤都走一遍,那么整个流程如下:

领域分析
ADT设计
编程实现
系统测试
系统部署

如果我们把编程实现、测试和部署抽象为系统实现,那么这个图会稍微好看一点。

领域分析
ADT设计
系统实现

当我们暂时把系统实现扔掉,那么整个流程就是:

领域分析
ADT设计

领域分析

领域驱动设计中,领域分析的核心内容系统的事件分析,一般会采用事件风暴(Event Storming)的方法来进行。在这个过程中,我们会把领域中的事件抽象为事件(Event),把事件中的数据抽象为值对象(Value Object),把事件中的操作抽象为实体(Entity)。

并进一步考虑事件的触发条件或者触发事件,以及事件的结果,这些都是领域中的事件,但是不是所有的事件都是我们需要关注的,我们只需要关注那些对我们的系统有意义的事件。这个过程最重要的原则就是,到底到边。

一直要事件的分析推到系统的边界上,或者是某个Actor的动作触发了事件,或者某个状态触发了事件,而事件的发生又会改变系统的状态,或者触发另外的事件。这其中比较重要的就是对现存系统的分析,以及对现存系统的边界的分析。

当通过事件风暴把系统的事件分析完毕之后,需要的就是进行事件的分类、排序,分析触发事件的命令,把一系列事件组合起来,形成一个个有逻辑的序列,在这个基础上,可进行子领域的划分,以及子领域之间的关系的分析。每个子领域应该对应特定的领域专家,或者是特定的团队,这样可以保证领域专家的专业性,也可以保证团队的独立性。

触发
成功
输出
失败
事件
命令
流程
后续事件
事件
事件
事件
异常
行为动作
定时事件
状态变化

事件的内涵外延、相互关系定义取得领域专家的一致意见后,需要领域专家进一步分析事件的输入和输出,事件的输入和输出就是事件的数据,这些数据可以是值对象,也可以是实体。这个过程中,需要领域专家对事件的输入和输出进行分析,然后把这些数据抽象为值对象或者实体。

所以领域分析大概内容就是事件分析、命令与业务流程、子领域与上下文等。

事件分析
命令与流程分析
领域深度分析
子领域的划分
子领域上下文
业务流程分析
输入输出分析

进一步ADT分析与设计,就可以形式化描述领域共享模型。

领域流程ADT

根据前面的分析,领域的模型由命令、事件和业务流程构成,并形成子领域、有界上下文,最终能够捕捉领域中的值的流动和业务信息。

在这个领域模型的核心,是信息传递和传唤的过程。这个过程可能称为流程、操作这类动词。在F#这类函数式编程中,则用函数来表达。

合法的输入集合
函数
合法的输出集合

这里三个元素:合法的输入集合、函数、合法的输出集合,都可以抽象为一个抽象数据类型(ADT),而ADT的组合数,就对应着输入输出的合法性以及函数对应关系。

这个样子,领域流程或者操作的编程对应就非常清楚,同样是一个ADT,可以表达为 A D T 1 ↦ A D T 2 ADT_1 \mapsto ADT_2 ADT1ADT2

所以领域的流程、流程的输入输出对应就是进行ADT设计,而对ADT的组合数则可用于实现关于合法的相关约束,这样才能做到非法状态不可表示。

ADT设计

ADT设计的核心就是对领域中的数据和操作进行抽象,这个过程中,我们需要把领域中的数据抽象为值对象或者实体,并用ADT来描述;并把领域中的操作抽象为ADT映射(同样是一个ADT)。

在ADT设计中,F#能提供什么支持呢?根据前面ADT的分析和学习,我们知道,ADT的两种基本形式就是Sum和Product。

Sum类型是OR的关系,Product类型是AND的关系。对领域中的值、表达式进行描述时,如果采用OR和AND来表示,大概会是:

data InputData = DataIDAND DataField1AND DataFiled2AND DataFiled3
data DataID = DataNameOR DataSerialNumber

上面这样的描述,可以将值的类型表达为领域专家所能够理解的形式,输入数据包括标识和数个字段;输入数据的标识可能是字符串也可能是序列号。

从前面ADT的分析和介绍看,组合数分析是非常总要的。因此,对于ADT中所包含的类型,需要进一步根据领域情况分析。例如

data DataName of string length in 12..255ascii a..z, A..Z, 0..9first 8 chars: valid date stringex. 20230830xxxx
data DataSerialNumber of int12 digitsfirst 8 digits: valid date stringlast 4 digits: serial number 0..9999ex. 202308301234

上面的信息,足够分析DataName的组合数。通过这样的分析和记录,就能够很好的搞清楚领域中的信息,并记录为整个团队都能很好理解的形式。

在领域分析和设计的阶段,并不需要专注于特定的语法和开发语言,关键是要清晰地分析和表达各个值的类型,要清晰到能够分析组合数的程度。

结论

  1. 领域分析可以采用领域的语言和领域的知识来完成,领域、子领域、上下文;
  2. 领域建模的核心就是把领域的数据、流程(输入输出和映射)描述为对应的ADT;
  3. F#等函数式编程工具通过对ADT的支持,提供了领域模型的绝佳对应,非常适合用于领域驱动开发。

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

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

相关文章

【AGC】云数据库API9开发问题汇总

【问题描述】 云数据库HarmonyOS API9 SDK已经推出了一段时间了,下面为大家汇总一些在集成使用中遇到的问题和解决方案。 【问题分析】 1. 报错信息:数据库初始化失败:{“message”:“The object type list and permission …

云原生Kubernetes:K8S常用服务端口

目录 一、理论 1.K8S常用服务端口号 一、理论 1.K8S常用服务端口号 (1)K8S集群 表1 K8S集群端口 协议端口号K8S集群TCP22使用主机驱动通过SSH进行节点配置TCP2376主机驱动与Docker守护进程通信的TLS端口TCP2379etcd客户端请求TCP2380etcd节点通信U…

PgSQL-并行查询系列-介绍[译]

PgSQL-并行查询系列-介绍 现代CPU模型拥有大量的CPU核心。多年来,数据库应用程序都是并发向数据库发送查询的。查询处理多个表的行时,若可以使用多核,则可以客观地提升性能。PgSQL 9.6引入了并行查询的新特性,开启并行查询后可以大…

es(Elasticsearch)介绍

学习es可以参考mysql(相比mysql而言,es所需的cpu、内存更多) 什么是Elasticsearch Elasticsearch简称es,是由Elastic和search组成。Elastic的意思是有弹性的,search的意思是搜索。 弹性:es是一个天生支持分…

笔记:linux中LED(GPIO)驱动设备树配置和用法

设备树中节点配置 设备树中的LED驱动一般是这样写&#xff0c;LED驱动可以控制GPIO的电平变化&#xff0c;生成文件节点很方便 leds: leds {compatible "gpio-leds";gpio_demo: gpio_demo {label "gpio_demo";gpios <&gpio0 RK_PC0 GPIO_ACTIV…

晶圆键合对准机的原理与应用

一、晶圆键合设备的工作原理 1、 第一个晶圆面朝下置于晶圆对准设备卡盘并传送到对准机内&#xff1b; 2、对准机内&#xff0c;晶圆在Z轴方向上移动直到被顶部的传输夹具真空吸附固定&#xff1b; 3、被传输夹具固定的第一个晶圆将成为后续对准工艺的基准&#xff0c;确定所…

51、基于注解方式开发Spring WebFlux,实现生成背压数据,就是实现一直向客户端发送消息

★ Spring WebFlux的两种开发方式 1. 采用类似于Spring MVC的注解的方式来开发。此时开发时感觉Spring MVC差异不大&#xff0c;但底层依然是反应式API。2. 使用函数式编程来开发★ 基于注解开发Spring WebFlux 开发上变化并不大&#xff0c;主要是处理方法的返回值可使用Mon…

大数据组件系列-Hadoop每日小问

1、谈谈对HDFS的理解&#xff1f;HDFS这种存储适合哪些场景&#xff1f; HDFS即Hadoop Distributed File System&#xff0c;Hadoop 分布式文件系统。它为的是解决海量数据的存储与分析的问题&#xff0c;它本身是源于Google在大数据方面的论文&#xff0c;GFS-->HDFS; HD…

Mybatis的三种映射关系以及联表查询

目录 一、概念 二、一对一 1、配置generatorConfig.xml 2、Vo包的编写 3、xml的sql编写 4、编写对应接口及实现类 5、测试 三、一对多 1、Vo包类的编写 2、xml的sql编写 3、编写对应接口及实现类 4、测试 四、多对多 1、Vo类 2、xml的sql配置 3、接口及接口实现…

文件编辑器、用户管理,嘎嘎学

打开文件 vim # 首先你先得下载这个插件 yum install -y vim vim 文件名 进入编辑模式 i #在光标所在处进入编辑模式 a #在当前光标后面进入编辑模式 o #在光标的下一行进入编辑模式 I #在光标所在处行首进入编辑模式 A #在光标所在处行尾进入编辑模式 O #在光标的上一…

本地使用GFPGAN进行图像人脸修复

人脸修复 1.下载项目和权重文件2.部署环境3.下载权重文件4.运行代码5.网页端体验 首先来看一下效果图 1.下载项目和权重文件 https://github.com/iptop/GFPGAN-for-Video.git2.部署环境 根据README文件部署好环境&#xff0c;额外还需要&#xff1a; cd GFPGAN-1.3.8 pyt…

介绍GitHub

GitHub 是一个基于互联网的源代码托管平台&#xff0c;可以帮助软件开发者存储和管理源代码&#xff0c;方便团队协作和版本控制。GitHub 的主要功能包括&#xff1a; 代码托管&#xff1a;开发者可以在 GitHub 上创建远程代码仓库&#xff0c;存储和管理他们的源代码。 版本控…

金融信创,软件规划需关注自主安全及生态建设

软件信创化&#xff0c;就是信息技术软件应用创新发展的意思&#xff08;简称为“信创”&#xff09;。 相信在中国&#xff0c;企业对于“信创化”这个概念并不陌生。「国强则民强」&#xff0c;今年来中国经济的快速发展&#xff0c;受到了各大欧美强国的“卡脖子”操作的影…

大数据面试题:MapReduce压缩方式

面试题来源&#xff1a; 《大数据面试题 V4.0》 大数据面试题V3.0&#xff0c;523道题&#xff0c;679页&#xff0c;46w字 可回答&#xff1a;1&#xff09;Hadoop常见的压缩算法有哪些&#xff1f; 问过的一些公司&#xff1a;网易云音乐(2022.11)&#xff0c;阿里(2020.…

css 文字单行多行超出长度后显示 ...

0.超出… 1、单行文本超出 <div class"content">测试数据&#xff1a;css单行文本超出显示省略号--------</div><style> .content{width: 200px;height: 200px;overflow:hidden;white-space: nowrap;text-overflow: ellipsis;-o-text-overflow:el…

Linux C++ 海康摄像头获取过车信息

代码 void CALLBACK MessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void *pUser) {printf("enter MessageCallback---------------------->\n");int i;NET_DVR_ALARMINFO_V30 struAlarmInfo;memcpy(&struAl…

【运维基础】文本编辑器---nano的使用

前言 Nano 是一个简单易用的命令行文本编辑器&#xff0c;下面是一些基本使用方法 文章目录 前言打开文件光标控制&#xff1a;保存和退出&#xff1a; 打开文件 你可以使用以下命令打开一个文件进行编辑&#xff1a; nano 文件名光标控制&#xff1a; 使用方向键&#xf…

微服务主流框架概览

微服务主流框架概览 目录概述需求&#xff1a; 设计思路实现思路分析1.HSF2.Dubbo 3.Spring Cloud5.gRPC Service mesh 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a be…

计算机图形学线性代数相关概念

Transformation&#xff08;2D-Model&#xff09; Scale(缩放) [ x ′ y ′ ] [ s 0 0 s ] [ x y ] (等比例缩放) \left[ \begin{matrix} x \\ y \end{matrix} \right] \left[ \begin{matrix} s & 0 \\ 0 & s \end{matrix} \right] \left[ \begin{matrix} x \\ y \en…

信创优选,国产开源。Solon v2.5.3 发布

Solon 是什么&#xff1f; 国产的 Java 应用开发框架。从零开始构建&#xff0c;有自己的标准规范与开放生态&#xff08;历时五年&#xff0c;具备全球第二级别的生态规模&#xff09;。与其他框架相比&#xff0c;解决了两个重要的痛点&#xff1a;启动慢&#xff0c;费内存…