领域建模刍议(一):分清问题域和问题解决域_火山石的博客-程序员宅基地

技术标签: Android  

一:领域与领域模型
  俗话说,人人心中有一个Hamlet,人人心中也都有一个领域模型的定义。
   常见的有:
   说法1:我理解的领域是对业务工作进行归类划分,归类的方式是业务工作具有相关的知识,这些所需要的知识构成一个领域,这些知识是业务工作的背景,通过对领域的分析,可以帮助我们挖掘、分析、理解业务工作的本质。 也就是说,领域是为需求分析工作服务的,它的目的是挖掘、分析、理解业务工作的本质。
   说法2:领域模型就是对领域内的概念类和现实世界中对象的可视化表示。
   说法3:企业应用架构模式中明确提出了三种领域逻辑组织模式:事务脚本、领域模型和表模块。领域模型同时将行为和数据作为领域逻辑的核心。
   从上面可以3种说法,可以看到不同上下文不同的观点,甚至未必是同一个表达对象。企业应用架构模式中的领域模型是设计到实现层的一个概念,而说法1,说法2种的领域是业务层面及分析阶段的一个概念。 因此,本文特指[领域模式]为业务视角的模型,引用定义如下:
  • 领域: 是相对于系统而言的,是系统要解决的现实问题。
  • 领域模型是对领域内的概念类或现实世界中对象的可视化表示(百度)
  • 领域模型是针对某个特定问题的所有相关方面的抽象模型(Wikipedia)

思考,如何对上图的元素建模?
 
二:领域建模的好处
领域建模的好处,有哪些?
2.1:不同角色统一语言、统一认知

如上图所示,客户需求历经演变之后已经面目全非,每一个加工制造环节都以为在[正确的做事]。君不见这样的生动局面一再上演:
产品经理宣讲prd,产品经理需要分别把名词翻译给业务方和开发人员,一则业务语言,一则技术语言。
几个架构师在小黑屋吵了半天,为了争论一个名词定义。
比如什么是支付?百度百科的解释:社会经济活动所引起的货币债权转移的过程。包括:交易、清算、结算。
那么对于下列情况是否属于支付范畴就是可以根据其内涵来比照了。
  • 用户A转账给B。
  • 用户通过某某网站还信用卡。
  • 用户在天猫购买了一个东西,使用花呗付款。
由此可见,显性的统一语言很重要,让干系人明白讨论的是一件事情。
2.2:对业务本质描述,抓到主旨
比如在支付宝渊源的发展过程中,我们先后使用有红包、实时优惠、商户优惠券等产品。这是烟囱式架构发展下的产物。
 
行业其它类似券的东东,如下图所示:

这3个产物我们锊一下:
  • 对于商户或者机构而言,这些是否可称之产品,可以面向商户售卖包括收费。
  • 对于用户而言,是否需要理解这3个东西不同的?这些认知对于营销,对于交易促成,对于品牌的好处是什么?
  • 对于支付宝平台而言,他们的管理模式有何区别?
  • 对于技术团队而言,他们是否可以抽象?
 
后来,我们在产品上形成了如下定义:
 
券定义:
是一种票据,作为券发行方和拥有方之间凭证,具有一定的价值和法律效应
相关干系方:
券的发放方[提供权益]
券的拥有方[享受权益]
劵的发放工具[是券发行方向拥有方发放券凭证的工具]
券形式:
以介质分类:纸质券,电子券
以使用方式分类:入场券,礼品券,提货券,代金券、红包,打折卡,满减卡等
可以把券作为基础产品,在业务形态上可以包装为打折卡,满减卡等用户感知的[产品]或者是[营销工具]。

三:领域模型=ER?
领域模型是否就是ER模型呢?答案是否定的,领域模型是特定业务域业务实体关系的自然浮现,而ER是设计阶段数据库实现关系的产物。
如下图所示,自然人Person在特定业务领域有2类,一类是客户(Customer),一类是雇员(Employee).

但究其实现而言,数据库设计有多种形态。
 


四:领域建模=DDD?
一说领域建模就提及DDD, 是大家的自然反应。因为DDD(2004年著名建模专家Eric Evans发表了他最具影响力的著名书籍:Domain-Driven Design –Tackling Complexity in the Heart of Software)的知名度颇高。我的观点是领域模型的产生是分析阶段的产品,分析是对需求及需求背后相关内容的挖掘,不用创造内容。DDD顾名思义是模型驱动设计,是从需求打通到设计阶段的方法。
 
阿白精辟的提炼出域模型的几个主要概念:
域(domain)
子域(subdomain): 
语境(context):是一个特定人群在讨论的问题域是所形成的上下文。 这里要强调一个概念, 特定人群不是以团队或者是项目为边界划分的人群, 而是以知识为边界来划分的人群。 也就是说上下文不是普遍存在的, 而是存在于一个人群内部的,并且这些上下文大多是以隐形知识(Tacit Knowledge)的方式而存在的。  什么是隐形知识呢, 就是还没有被总结整理归纳沉淀的知识。 举例来说说AliExpress商品团队会有一个独立详情页和商铺详情页的概念, 这两个概念的准确定义和他们的商业目标的定义目前还没有显现化。 但是几乎团队内的每个人都能分别出这两个概念和他们所关联的问题。 这就是一个语境(Context)。
特定语境(Bounded context):是把上下文限定到某个特定的边界之内。 这个边界是由某个特定人群和他们所讨论的问题子域来决定的。 举例来从电子商务,到商品, 到商品发布, 到规则,到商品审核规则是从大到小的问题域,他们对应的特定语境就是越来越细分并且越来越准确的上下文, 而对应的人群也是越来越小并且越来越专业。  最常见的bounded Context就是某个国际标准组织, 他们会为自己的标准定义专业的名词, 语法, 和表达方式。 而一个大的标准,比如说Health Level 7 (HL7), 总共有数千的会员。 这些人又组成了更小的标准委员会。标准委员会内又有更小的讨论组。 这就形成的从大到小的分级。而另外一个医疗标准, DICOM,又形成了另外一个bounded context。
语境映射(Context Mapping):不同的语境之间会有交互, 那么从一个语境到另一个语境的翻译过程就是语境映射。 比如说刚才提到的HL7是一个医疗标准。 而DICOM是一个医疗图像标准。 每个语境有一套完整准确的定义。 那么当某个场景需要我们在两个语境之间做交互的时候, 我们就需要Context Mapping 了。 举个例子来说,一个普通咳嗽的病人可能会被医生推荐去做胸透, 那么信息就需要从一个只能理解HL7(医疗语境)的系统交换到DICOM(医疗图像语境)的系统。 那么在HL7系统中的模型就需要无损的映射到DICOM系统中去。 这就是个映射的例子。     
域语言(Ubiquitous  Language): 
实体(Entity)
触发事件(Domain Event): 
数值对象(Value Object):   
实体类型(Entity Type)
关系(Relationship)
场景(Scenario)
核心场景(Core Scenario)
不照搬相应解释了,大家可以根据link过去看原文。我对这部分内容有一些浅见补充:
  • 不建议在分析阶段区别Entity和Value Object。比如Customer和Adress的关系和区别一样,在后续精细化过程中,认识自然就清楚了,比如Adress是可以复用的,非唯一的。
  • 在域模型中可以增加业务规则作为补充。比如下图在送货单和订单项的关系上有一行约束说明:只有当所有订单项都已经送到,才能成功关闭订单。
我们来看看 DDD的内容那些是领域建模(分析阶段应该识别的)。
 
如上图所示,在分析阶段可以用的至多有entity、value object。
再次论证了DDD是一个重在Design的工具。
基于上面域,域语言,不难理解不同域同一名词的含义不同,即使是同一介质它的内涵和外延也不同,我们可以把域表述为问题域。
比如电子商务网站有优惠券,包括天猫购物券、店铺券、商品优惠券等。
还有一个专门做券导航的网站:券妈妈
他们管理的都是券,但是业务实体[券]是有差异的,因为它们要解决的问题域不同。券妈妈是一个流量入口,关注领用和跳转;而淘宝券关注使用情况,包括对店铺的黏性等。业务实体的业务行为,状态也有有所差异。
五:问题域vs问题解决域
最后总结一下,问题域和问题解决域是2个范畴,分属分析、设计及实现阶段,在不同阶段使用的工具和目标也有所差异。
在分析阶段的领域模型中,我觉得主要描述领域实体及关系,可以辅助领域名词解释(可业务字典形式)、以及约束(业务规则),而业务实体(域实体)仅描述主特征即可。
 
未完待续。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhangcanyan/article/details/51823292

智能推荐

索引贴——移动开发(.Net CF 停止更新)_weixin_30596735的博客-程序员宅基地

这是关于本人博客的技术索引贴,希望能方便的让您阅读到相关技术文章——不断更新中。一整理才发现,好多啊,哈哈~一、.Net CF技巧:搜集、转载一些和CF开发相关的辅助文章,比较适合初学者、开发入门者。『原创』关于“手机拍照识别二维码”WM版运行中的小问题及解决~『原创』+『参考』亲手实验:使用C#在PPC中播放声音 『原创』+『参考』使用C#在PPC的Today界面上的任务栏加入应...

Unity 打包后错误捕捉_带着你江湖里逍遥的博客-程序员宅基地

Unity在Editor开发时可以在控制台查看错误,然而一旦发布,这些错误就无法被开发人员直接看到,会引起程序不按照预期进行导致表现不正确。好在Unity本身具有非常强大的日志捕获,具体代码如下using UnityEngine;using System;using System.IO;using System.Diagnostics;using System.Collections...

java.sql.SQLException: Unsupported character encoding 'utf8mb4'._Vincent8080的博客-程序员宅基地

版权声明:本文为 testcs_dn(微wx笑) 原创文章,非商用自由转载-保持署名-注明出处,谢谢。 https://blog.csdn.net/testcs_dn/article/details/76199827 四月 12, 201...

【数据库】MySQL中where和having的用法区别_浪里小飞侠的博客-程序员宅基地

MySQL中where和having的用法区别having一般跟在group by之后,执行记录组选择的一部分来工作的。where则是执行所有数据来工作的。再者having可以用聚合函数,如having sum(qty)>10001、having的用法having字句可以让我们筛选成组后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和having字句前。而 having子句在聚合后对组记录进行筛选。我的理解就是真实表中没有此数据,这些数据是通过一些函数生存。/

docker安装rabbitmq延时插件rabbitmq_delayed_message_exchange_花哥码天下的博客-程序员宅基地

第一种方式是进入容器内部去安装 首先下载镜像和启动 rabbitmq: restart: always image: rabbitmq:management container_name: rabbitmq ports: - 5672:5672 - 15672:15672 networks: default: ipv4_address: 172.18.0.5 environment: ...

操作系统课设——页面置换算法的模拟_linux 模拟页面置换算法_啊啊啊啊啊啊啊阿的博客-程序员宅基地

本课设主要实现FIFO算法和LRU算法,虽然实现了功能,但是个人感觉代码可以优化,而且采用的主存块数是3,如果主存块数修改了,那么代码也需要修改,这是我课设不足之处,望大神来指教!下面是我的代码#include #include #define PAGE_NUM 3 //主存块数#define SERIAL_NUM 12 //访问序列的次数int serial[SERI

随便推点

LeetCode 之 DFS 深度优先遍历_leetcode 深度优先遍历_Mavs的博客-程序员宅基地

1. Palindrome Partioning IIGiven a string s, partition s such that every substring of the partition is a palindrome.Return all possible palindrome partitioning of s.For example, given s 

JAVA获取CPUID、主板序列号、硬盘序列号、MAC地址(自己验证过)_linhaibing009的博客-程序员宅基地

最近在修改公司licence程序,需要获取到更多的硬件唯一标识,以便加密使用。网上看了很多大神的博客,思路大概整理了一下,根据系统类型分为两种方式:一、windows通过创建vbs脚本,然后使用Runtime.getRuntime().exec()执行脚本,获取序列号等信息。二、LINUXlinux系统其实差不多,同样使用Runtime.getRuntime().exec()执行...

【Matlab优化预测】贝叶斯网络优化LSTM预测【含源码 1158期】_贝叶斯优化lstm模型建立步骤_Matlab佛怒唐莲的博客-程序员宅基地

一、代码运行视频(哔哩哔哩)【Matlab优化预测】贝叶斯网络优化LSTM预测【含源码 1158期】二、matlab版本及参考文献1 matlab版本2014a2 参考文献[1]王丁,罗文波,吴琼,赵震波,王云锋.基于LSTM网络模型的航天器热变形预测[J]. 机电产品开发与创新. 2021,34(02)...

深度学习 | 《深度学习入门之PyTorch》阅读笔记_JUST LOVE SMILE的博客-程序员宅基地

文章目录深度学习入门之PyTorch第一章 深度学习介绍1.1 人工智能1.2 数据挖掘,机器学习和深度学习1.2.1 数据挖掘1.2.2 机器学习1.2.3 深度学习第二章 深度学习框架2.1 深度学习框架介绍2.2 PyTorch介绍2.2.1 什么是PyTorch2.2.2 为什么使用PyTorch2.3 配置PyTorch深度学习环境2.3.1 操作系统2.3.2 Python开发环境的安装2.3.3 PyTorch安装第三章 多层全连接神经网络3.1 PyTorch基础3.1.1 Tensor张量

基于Spring可扩展Schema提供自定义配置支持_hanruikai的博客-程序员宅基地

在很多情况下,我们需要为系统提供可配置化支持,简单的做法可以直接基于Spring的标准Bean来配置,但配置较为复杂或者需要更多丰富控制的时候,会显得非常笨拙。一般的做法会用原生态的方式去解析定义好的xml文件,然后转化为配置对象,这种方式当然可以解决所有问题,但实现起来比较繁琐,特别是是在配置非常复杂的时候,解析工作是一个不得不考虑的负担。Spring提供了可扩展Schema的支持,这是一个不错