怎么接单做网站,专门找人做软件的网站,做公号模版网站,淘宝做短视频网站好前言
采用ADT来对领域进行设计#xff0c;是一种很好的实践。在这种实践中#xff0c;我们可以把领域中的数据抽象成ADT#xff0c;把领域中的操作抽象成函数#xff0c;然后利用ADT的类型系统来进行类型检查#xff0c;从而保证领域中的数据和操作的正确性。
设计目标 …前言
采用ADT来对领域进行设计是一种很好的实践。在这种实践中我们可以把领域中的数据抽象成ADT把领域中的操作抽象成函数然后利用ADT的类型系统来进行类型检查从而保证领域中的数据和操作的正确性。
设计目标
首先我们的设计目标如下
各领域专家架和程序开发都能够理解的设计能够利用ADT的类型系统来进行类型检查不需要与具体的编程语言乃至编程范式绑定
设计原则
那么我们需要遵循大概以下的原则
描述ADT的术语应该尽量与领域中的术语一致描述ADT的数据结构应该尽量与领域中的数据结构一致描述ADT的操作应该尽量与领域中的操作一致ADT的分析应该专注于组合而不是继承ADT的各个组合部分都应该都领域含义而非编程语言的实现细节编程实现的细节例如基本数据类型、数据结构和算法的实现在设计阶段应该被忽略
软件开发流程
从本质上来看所有的设计都应该是迭代的。不过我们还是可以首先给出一个线性的流程然后再给出检查点并定义迭代的流程。
首先是整个软件系统开发的流程如果我们非常丧心病狂并且非常注重完备性务必要把所有的步骤都走一遍那么整个流程如下 #mermaid-svg-XtvtWQu4AUD6tIOa {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-XtvtWQu4AUD6tIOa .error-icon{fill:#552222;}#mermaid-svg-XtvtWQu4AUD6tIOa .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XtvtWQu4AUD6tIOa .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-XtvtWQu4AUD6tIOa .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XtvtWQu4AUD6tIOa .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XtvtWQu4AUD6tIOa .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XtvtWQu4AUD6tIOa .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XtvtWQu4AUD6tIOa .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XtvtWQu4AUD6tIOa .marker.cross{stroke:#333333;}#mermaid-svg-XtvtWQu4AUD6tIOa svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XtvtWQu4AUD6tIOa .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-XtvtWQu4AUD6tIOa .cluster-label text{fill:#333;}#mermaid-svg-XtvtWQu4AUD6tIOa .cluster-label span{color:#333;}#mermaid-svg-XtvtWQu4AUD6tIOa .label text,#mermaid-svg-XtvtWQu4AUD6tIOa span{fill:#333;color:#333;}#mermaid-svg-XtvtWQu4AUD6tIOa .node rect,#mermaid-svg-XtvtWQu4AUD6tIOa .node circle,#mermaid-svg-XtvtWQu4AUD6tIOa .node ellipse,#mermaid-svg-XtvtWQu4AUD6tIOa .node polygon,#mermaid-svg-XtvtWQu4AUD6tIOa .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XtvtWQu4AUD6tIOa .node .label{text-align:center;}#mermaid-svg-XtvtWQu4AUD6tIOa .node.clickable{cursor:pointer;}#mermaid-svg-XtvtWQu4AUD6tIOa .arrowheadPath{fill:#333333;}#mermaid-svg-XtvtWQu4AUD6tIOa .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-XtvtWQu4AUD6tIOa .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-XtvtWQu4AUD6tIOa .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-XtvtWQu4AUD6tIOa .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-XtvtWQu4AUD6tIOa .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-XtvtWQu4AUD6tIOa .cluster text{fill:#333;}#mermaid-svg-XtvtWQu4AUD6tIOa .cluster span{color:#333;}#mermaid-svg-XtvtWQu4AUD6tIOa div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-XtvtWQu4AUD6tIOa :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 领域分析 ADT设计 编程实现 系统测试 系统部署 如果我们把编程实现、测试和部署抽象为系统实现那么这个图会稍微好看一点。 #mermaid-svg-i7WI2urmfKb9lQcn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-i7WI2urmfKb9lQcn .error-icon{fill:#552222;}#mermaid-svg-i7WI2urmfKb9lQcn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-i7WI2urmfKb9lQcn .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-i7WI2urmfKb9lQcn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-i7WI2urmfKb9lQcn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-i7WI2urmfKb9lQcn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-i7WI2urmfKb9lQcn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-i7WI2urmfKb9lQcn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-i7WI2urmfKb9lQcn .marker.cross{stroke:#333333;}#mermaid-svg-i7WI2urmfKb9lQcn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-i7WI2urmfKb9lQcn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-i7WI2urmfKb9lQcn .cluster-label text{fill:#333;}#mermaid-svg-i7WI2urmfKb9lQcn .cluster-label span{color:#333;}#mermaid-svg-i7WI2urmfKb9lQcn .label text,#mermaid-svg-i7WI2urmfKb9lQcn span{fill:#333;color:#333;}#mermaid-svg-i7WI2urmfKb9lQcn .node rect,#mermaid-svg-i7WI2urmfKb9lQcn .node circle,#mermaid-svg-i7WI2urmfKb9lQcn .node ellipse,#mermaid-svg-i7WI2urmfKb9lQcn .node polygon,#mermaid-svg-i7WI2urmfKb9lQcn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-i7WI2urmfKb9lQcn .node .label{text-align:center;}#mermaid-svg-i7WI2urmfKb9lQcn .node.clickable{cursor:pointer;}#mermaid-svg-i7WI2urmfKb9lQcn .arrowheadPath{fill:#333333;}#mermaid-svg-i7WI2urmfKb9lQcn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-i7WI2urmfKb9lQcn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-i7WI2urmfKb9lQcn .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-i7WI2urmfKb9lQcn .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-i7WI2urmfKb9lQcn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-i7WI2urmfKb9lQcn .cluster text{fill:#333;}#mermaid-svg-i7WI2urmfKb9lQcn .cluster span{color:#333;}#mermaid-svg-i7WI2urmfKb9lQcn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-i7WI2urmfKb9lQcn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 领域分析 ADT设计 系统实现 当我们暂时把系统实现扔掉那么整个流程就是 #mermaid-svg-UzvtsWWaRenGDocf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-UzvtsWWaRenGDocf .error-icon{fill:#552222;}#mermaid-svg-UzvtsWWaRenGDocf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UzvtsWWaRenGDocf .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-UzvtsWWaRenGDocf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UzvtsWWaRenGDocf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UzvtsWWaRenGDocf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UzvtsWWaRenGDocf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UzvtsWWaRenGDocf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UzvtsWWaRenGDocf .marker.cross{stroke:#333333;}#mermaid-svg-UzvtsWWaRenGDocf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UzvtsWWaRenGDocf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-UzvtsWWaRenGDocf .cluster-label text{fill:#333;}#mermaid-svg-UzvtsWWaRenGDocf .cluster-label span{color:#333;}#mermaid-svg-UzvtsWWaRenGDocf .label text,#mermaid-svg-UzvtsWWaRenGDocf span{fill:#333;color:#333;}#mermaid-svg-UzvtsWWaRenGDocf .node rect,#mermaid-svg-UzvtsWWaRenGDocf .node circle,#mermaid-svg-UzvtsWWaRenGDocf .node ellipse,#mermaid-svg-UzvtsWWaRenGDocf .node polygon,#mermaid-svg-UzvtsWWaRenGDocf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-UzvtsWWaRenGDocf .node .label{text-align:center;}#mermaid-svg-UzvtsWWaRenGDocf .node.clickable{cursor:pointer;}#mermaid-svg-UzvtsWWaRenGDocf .arrowheadPath{fill:#333333;}#mermaid-svg-UzvtsWWaRenGDocf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-UzvtsWWaRenGDocf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-UzvtsWWaRenGDocf .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-UzvtsWWaRenGDocf .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-UzvtsWWaRenGDocf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-UzvtsWWaRenGDocf .cluster text{fill:#333;}#mermaid-svg-UzvtsWWaRenGDocf .cluster span{color:#333;}#mermaid-svg-UzvtsWWaRenGDocf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-UzvtsWWaRenGDocf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 领域分析 ADT设计 领域分析
领域驱动设计中领域分析的核心内容系统的事件分析一般会采用事件风暴Event Storming的方法来进行。在这个过程中我们会把领域中的事件抽象为事件Event把事件中的数据抽象为值对象Value Object把事件中的操作抽象为实体Entity。
并进一步考虑事件的触发条件或者触发事件以及事件的结果这些都是领域中的事件但是不是所有的事件都是我们需要关注的我们只需要关注那些对我们的系统有意义的事件。这个过程最重要的原则就是到底到边。
一直要事件的分析推到系统的边界上或者是某个Actor的动作触发了事件或者某个状态触发了事件而事件的发生又会改变系统的状态或者触发另外的事件。这其中比较重要的就是对现存系统的分析以及对现存系统的边界的分析。
当通过事件风暴把系统的事件分析完毕之后需要的就是进行事件的分类、排序分析触发事件的命令把一系列事件组合起来形成一个个有逻辑的序列在这个基础上可进行子领域的划分以及子领域之间的关系的分析。每个子领域应该对应特定的领域专家或者是特定的团队这样可以保证领域专家的专业性也可以保证团队的独立性。 #mermaid-svg-3bG29cDkUUVHLttd {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3bG29cDkUUVHLttd .error-icon{fill:#552222;}#mermaid-svg-3bG29cDkUUVHLttd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3bG29cDkUUVHLttd .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-3bG29cDkUUVHLttd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3bG29cDkUUVHLttd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3bG29cDkUUVHLttd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3bG29cDkUUVHLttd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3bG29cDkUUVHLttd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3bG29cDkUUVHLttd .marker.cross{stroke:#333333;}#mermaid-svg-3bG29cDkUUVHLttd svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3bG29cDkUUVHLttd .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3bG29cDkUUVHLttd .cluster-label text{fill:#333;}#mermaid-svg-3bG29cDkUUVHLttd .cluster-label span{color:#333;}#mermaid-svg-3bG29cDkUUVHLttd .label text,#mermaid-svg-3bG29cDkUUVHLttd span{fill:#333;color:#333;}#mermaid-svg-3bG29cDkUUVHLttd .node rect,#mermaid-svg-3bG29cDkUUVHLttd .node circle,#mermaid-svg-3bG29cDkUUVHLttd .node ellipse,#mermaid-svg-3bG29cDkUUVHLttd .node polygon,#mermaid-svg-3bG29cDkUUVHLttd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3bG29cDkUUVHLttd .node .label{text-align:center;}#mermaid-svg-3bG29cDkUUVHLttd .node.clickable{cursor:pointer;}#mermaid-svg-3bG29cDkUUVHLttd .arrowheadPath{fill:#333333;}#mermaid-svg-3bG29cDkUUVHLttd .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3bG29cDkUUVHLttd .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3bG29cDkUUVHLttd .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-3bG29cDkUUVHLttd .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-3bG29cDkUUVHLttd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3bG29cDkUUVHLttd .cluster text{fill:#333;}#mermaid-svg-3bG29cDkUUVHLttd .cluster span{color:#333;}#mermaid-svg-3bG29cDkUUVHLttd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3bG29cDkUUVHLttd :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 触发 成功 输出 失败 事件 命令 流程 后续事件 事件 事件 事件 异常 行为动作 定时事件 状态变化 事件的内涵外延、相互关系定义取得领域专家的一致意见后需要领域专家进一步分析事件的输入和输出事件的输入和输出就是事件的数据这些数据可以是值对象也可以是实体。这个过程中需要领域专家对事件的输入和输出进行分析然后把这些数据抽象为值对象或者实体。
所以领域分析大概内容就是事件分析、命令与业务流程、子领域与上下文等。 #mermaid-svg-8aiZrN5qsqzLXl83 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-8aiZrN5qsqzLXl83 .error-icon{fill:#552222;}#mermaid-svg-8aiZrN5qsqzLXl83 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8aiZrN5qsqzLXl83 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-8aiZrN5qsqzLXl83 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8aiZrN5qsqzLXl83 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8aiZrN5qsqzLXl83 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8aiZrN5qsqzLXl83 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8aiZrN5qsqzLXl83 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8aiZrN5qsqzLXl83 .marker.cross{stroke:#333333;}#mermaid-svg-8aiZrN5qsqzLXl83 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8aiZrN5qsqzLXl83 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8aiZrN5qsqzLXl83 .cluster-label text{fill:#333;}#mermaid-svg-8aiZrN5qsqzLXl83 .cluster-label span{color:#333;}#mermaid-svg-8aiZrN5qsqzLXl83 .label text,#mermaid-svg-8aiZrN5qsqzLXl83 span{fill:#333;color:#333;}#mermaid-svg-8aiZrN5qsqzLXl83 .node rect,#mermaid-svg-8aiZrN5qsqzLXl83 .node circle,#mermaid-svg-8aiZrN5qsqzLXl83 .node ellipse,#mermaid-svg-8aiZrN5qsqzLXl83 .node polygon,#mermaid-svg-8aiZrN5qsqzLXl83 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8aiZrN5qsqzLXl83 .node .label{text-align:center;}#mermaid-svg-8aiZrN5qsqzLXl83 .node.clickable{cursor:pointer;}#mermaid-svg-8aiZrN5qsqzLXl83 .arrowheadPath{fill:#333333;}#mermaid-svg-8aiZrN5qsqzLXl83 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8aiZrN5qsqzLXl83 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8aiZrN5qsqzLXl83 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-8aiZrN5qsqzLXl83 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-8aiZrN5qsqzLXl83 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8aiZrN5qsqzLXl83 .cluster text{fill:#333;}#mermaid-svg-8aiZrN5qsqzLXl83 .cluster span{color:#333;}#mermaid-svg-8aiZrN5qsqzLXl83 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8aiZrN5qsqzLXl83 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 事件分析 命令与流程分析 领域深度分析 子领域的划分 子领域上下文 业务流程分析 输入输出分析 进一步ADT分析与设计就可以形式化描述领域共享模型。
领域流程ADT
根据前面的分析领域的模型由命令、事件和业务流程构成并形成子领域、有界上下文最终能够捕捉领域中的值的流动和业务信息。
在这个领域模型的核心是信息传递和传唤的过程。这个过程可能称为流程、操作这类动词。在F#这类函数式编程中则用函数来表达。 #mermaid-svg-frecdgbIHWTk9vus {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-frecdgbIHWTk9vus .error-icon{fill:#552222;}#mermaid-svg-frecdgbIHWTk9vus .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-frecdgbIHWTk9vus .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-frecdgbIHWTk9vus .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-frecdgbIHWTk9vus .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-frecdgbIHWTk9vus .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-frecdgbIHWTk9vus .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-frecdgbIHWTk9vus .marker{fill:#333333;stroke:#333333;}#mermaid-svg-frecdgbIHWTk9vus .marker.cross{stroke:#333333;}#mermaid-svg-frecdgbIHWTk9vus svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-frecdgbIHWTk9vus .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-frecdgbIHWTk9vus .cluster-label text{fill:#333;}#mermaid-svg-frecdgbIHWTk9vus .cluster-label span{color:#333;}#mermaid-svg-frecdgbIHWTk9vus .label text,#mermaid-svg-frecdgbIHWTk9vus span{fill:#333;color:#333;}#mermaid-svg-frecdgbIHWTk9vus .node rect,#mermaid-svg-frecdgbIHWTk9vus .node circle,#mermaid-svg-frecdgbIHWTk9vus .node ellipse,#mermaid-svg-frecdgbIHWTk9vus .node polygon,#mermaid-svg-frecdgbIHWTk9vus .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-frecdgbIHWTk9vus .node .label{text-align:center;}#mermaid-svg-frecdgbIHWTk9vus .node.clickable{cursor:pointer;}#mermaid-svg-frecdgbIHWTk9vus .arrowheadPath{fill:#333333;}#mermaid-svg-frecdgbIHWTk9vus .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-frecdgbIHWTk9vus .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-frecdgbIHWTk9vus .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-frecdgbIHWTk9vus .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-frecdgbIHWTk9vus .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-frecdgbIHWTk9vus .cluster text{fill:#333;}#mermaid-svg-frecdgbIHWTk9vus .cluster span{color:#333;}#mermaid-svg-frecdgbIHWTk9vus div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-frecdgbIHWTk9vus :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 合法的输入集合 函数 合法的输出集合 这里三个元素合法的输入集合、函数、合法的输出集合都可以抽象为一个抽象数据类型ADT而ADT的组合数就对应着输入输出的合法性以及函数对应关系。
这个样子领域流程或者操作的编程对应就非常清楚同样是一个ADT可以表达为 A D T 1 ↦ A D T 2 ADT_1 \mapsto ADT_2 ADT1↦ADT2 。
所以领域的流程、流程的输入输出对应就是进行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的组合数。通过这样的分析和记录就能够很好的搞清楚领域中的信息并记录为整个团队都能很好理解的形式。
在领域分析和设计的阶段并不需要专注于特定的语法和开发语言关键是要清晰地分析和表达各个值的类型要清晰到能够分析组合数的程度。
结论
领域分析可以采用领域的语言和领域的知识来完成领域、子领域、上下文领域建模的核心就是把领域的数据、流程输入输出和映射描述为对应的ADTF#等函数式编程工具通过对ADT的支持提供了领域模型的绝佳对应非常适合用于领域驱动开发。