浅析领域驱动设计

1.概要

DDD(Domain-driven design,模型驱动设计)是一种软件设计的指导思想,而非固定的一套公式化开发模板(这样就会导致网络上出现各种基于自己或业务上的理解而产出的DDD落地的实现,会让很想学习的开发者迷茫)。在项目的全生命周期内,所有岗位的人员都基于对业务的相同的理解来展开工作。所有人员站在用户的角度、业务的角度区思考问题,而不是从一开始就站在技术的角度去思考。

       在项目初期,需要将领域专家引入到团队中。那什么是领域专家呢?他应该是谁?领域专家是指对业务领域非常熟悉(或在该业务领域耕耘了很多年)。他可以是团队中的任何人,项目经理、产品经理、架构师等等都可以是领域专家,在需求分析阶段大家都需要对需求整体进行评估。团队需要思考这几个问题,是否需要使用DDD?现有的团队人员是否能支撑起DDD?任何技术或者设计都需要整体的评估,而不是一味地去迎合。

       接下来让我们看看什么是领域驱动设计。

f9a02b64913bf961f507459bd2dc057f.png

1.1需求分析

需求分析的方式有很多,例如:用例法,四色建模法。其目的就是为了去建立领域模型的认知。以上两种方法可能会有些抽象,在项目前期与客户沟通过程属于需求分析层面该如何去做。就需要一种统一的一种规则,需要统一语言。接下来就是介绍Domain Story Telling这个概念(这个概念是由domainstorytelling.org网站提出)。包含下图的四个部分。

be7b8d234da0a878348dae28768902fe.png

由项目经理或产品经理通过这四种概念对需求进行梳理,通过这种方式可以很清楚直白的表达出业务场景。那么这四个部分各代表什么含义呢?

  • Pictograms and Vocabulary(象形图和词汇)

    • 1.Actors(角色),(故事场景的参与者,故事指的是功能点)。

    • 2.WorkObjects(参与者与参与者之间传递的内容,或需要呈现的内容称为工作对象)。

    • 3.Acivities(代表的Actors和WorkObjects之间关系,用线的方式来表示)。

    • 4.Annotations(所有流程的注解)。

基于以上概念画出来的图大概是这样,图中大致描述的是电商购物的一个流程分析。

a70b6d38801c194f4c39208c053a6f90.png

以商城购物系统为例。

(1)用户查看商品,向购物网站发送商品列表请求信息。

ba8483a89d6184aaedac492ca047c506.png

(2)购物网站响应商品信息给客户。

e82d0242206f65cce033dde6a985b2e1.png

(3)用户选择商品、购买,发送购买商品请求

b8701f14a5722ebcbe2bccd3f44e3c67.png

(4)购物网站响应订单信息给客户。此时订单是未支付的。

(4.1)用户拿到订单信息之后,开始支付。发送支付请求。

60f35d752ec33c869e30ca5562b8c363.png

(5)购物网站根据用户提供的支付信息,去(银行系统)对应的银行账户中进行扣款。

(5.1)扣款成功之后,再将扣款成功的订单信息返回给购物网站。

621dc5023b0ea1f02d81cf3ef4913a02.png

(6)购物网站拿到扣款成功的订单信息之后,开始通知仓库管理员准备发货。(6.1)并且通知用户,扣款成功购物网站准备发货了。

320204024b04c7350faca94206629214.png

(7)仓库管理员拿到货物之后打包发送给快递员。

4506dda7303076035ccdeed18d5d3f21.png

(8)快递员送货上门给客户。

8fa96f71fe87c119a08ad1579710ab95.png

基于以上的分析,大家可以清楚的了解到商城购物的整个环节。

1.2领域分析

领域(Domain ) :一个组织做的事情(举个比较狭隘的例子,阿里这个组织做的事情就是做电商)。

子域

  • 核心域:解决项目核心问题,和组织业务紧密关联。

  • 支撑域:解决项目的非核心问题,则具有组织特性,但不具有通用性。

  • 通用域:通用特性,没有组织特性。

  • 关心的业务重点不同,领域的划分也不同。

d2f4aa793dee1788d62b251c90f963c5.png

项目初期应考虑的是如何领域建模,用业务语言去描述和构建系统。而不是用技术语言,去思考代码怎么写。技术是服务于业务的脱离业务谈技术或者架构、设计都是空谈。

(1)商品浏览核心域

(2)选择购买商品、支付订单

(3)订单支付,银行交互

(4)发货、仓库管理

(5)配送

目前我们暂时先把购物到配送整个过程划分为五个子域,为什么不是四部分?为什么不是三部分?这个没有明确的标准取决于分析者的当前对业务的理解,站在现有的角度去分析领域边界。并不是说谁做就会更好,符合当前场景下的分析即可。那么划分领域的原则是什么呢?原则是业务并不是功能,围绕的是业务的走向划分而不是以业务的功能点划分。

有了领域边界之后,就开始绘制领域的边界图。那么又会引出新的问题,边界和边界之间存在什么样的关系?是如何交互的?

329e5d7f04431c75e2f8e140d69f7d39.png

站在系统的角度从商品的查询到最终的发货是一个整体的流程。

(1)查询商品的边界和订单的数据做交互(2)订单需要跟支付、仓库做交互(3)仓库跟物流送货做交互那么为了让领域的内聚性更强,会需要去对领域做一个保护。保护手段有三种:防腐层(ACL)、开放主机服务(OHS)、发布语言(PL)。

防腐层(ACL)

通过适配器,桥接模式、外观模式对于访问操作的一种保护。查询商品和订购商品之间的交互是通过一个接口来实现的。定义这个接口是为了不影响别人是需要做一个处理,这个接口不会因为你的领域类的变化而影响接口的定义,我就不会去关心你的内部实现了只考虑在接口层面怎么去交互。接口的表现形式有很多种,在项目中可以是一个接口,在多个项目中可以是一个协议。例如reset api也是一种接口的实现,OSH/OL相当于就是做两个根本不在一起的服务进行交互的一种方式。ACL可以理解为它是一种接口(Interface)层面的定义,D和U就是Down和UP用于区分上下级的关系。以查询商品和订购商品(订单)举例,如果需要做防腐层应该在哪个边界中去做呢?答案是在查询商品,因为不管你商品是什么样的,对于订单来说查询商品属于低层。而对于PL(订购支付)来说就不是了,订购支付属于高层所以订购商品需要主动去做防腐处理。

1.3 Domain Design

b96e7be5ac874701bcd0a1d394d5a2bc.png

(领域建模工具,推荐使用:StarUML,或微软的Viso)

BoundedContext(界限上下文)https://thedomaindrivendesign.io/bounded-context/

Aggregate(聚合根)

聚合根相当于领域中的一个大对象,它其实是由多个Entities和多个Value Obiect组成。它是操作具体业务流程中的关键点,它会由创建它的方法比如说Factories当然也可以去new。

Entities

Entities是有id的唯一标识的,有状态的对象。比如说商城中订单就是这样一个概念。

Value Obiect

是一个无状态的值对象,订单中包含的那些数据可以看作成值对象,例如收货信息address无论这些字段的数值如何改变都不会影响订单的状态而发生改变,只会影响数据不会影响状态。

Services

在Entities满足不了需要的情况下,它操作的都是无状态的数据对象和逻辑。需要先考虑这两条规则。例如转账功能,有AB两个账户,AB都有一个Entities对象,那么谁转账给谁呢?如果在Entities做一个转账好像又不是那么合理,所以会提出一个转账的Services,需要传递两个账户的Content来完成转账的服务。不能在Entities体现这个业务,这个业务是无状态的,这个业务不会去影响Entities的状态只是去做了一个业务逻辑的处理。这种情况下是可以用Services去做的。在DDD中需要弱化Services,大家不要把领域模型花了那么大心思去分析的业务,又大部分通过Services去实现成为了一个数据驱动的开发方式上。所以在做领域设计的时候大家一定要想清楚当时定义的意思和作用。

DomainEvents

因为Entities是有生命周期的且有状态改变的,它很多业务的一些触发条件都是因为这些状态改变而触发的,所以这个领域事件可以关联很多业务的执行逻辑。例如:订单支付完成付款之后,是需要根银行进行交互的,当银行将订单数据返回给商城之后。需要触发两个事件,第一个通知用户,第二个通知仓库管理员。这两件事情的完成都是需要基于支付完订单之后通知给下游的两个领域。所以我们就需要知道领域事件可以作为领域边界触发的一种行为,也可以立即为是解耦的一种方式。如果用领域事件的方式去实现业务那么可以拆分的更细。DomainEvents结合事务的一个分享。分布式事务里的事务消息问题,我们是把一个业务划分为主次的,这个业务关系是相对的。以银行扣款支付成功之后触发两条业务线为例子,什么是主呢?银行的消息提醒给你已经支付成功了这个业务,这是一个主业务,那么它的延申业务有两个(1)通知仓库管理员去发货(2)通知用户支付成功。在实现业务的时,接收银行返回支付状态改变的时候去触发两个事件给延申业务。站在事务的角度上来说,需要满足主线的业务事务提交两个延申的业务,提交之后就不做管理了成功就成功失败就失败,主线就是主线延申就是延申。本地事务提交了才会发送事务消息。事务消息发送完成之后,由两个订阅者去完成各自的业务逻辑,如果失败了也可以通过事务消息来做重复的事务补偿。

Factories

是为了创建Entities和Aggregate的对象,Aggregate实际上也是一个Entities对象,Aggregate只是一个概念实际对应的还是一个对象。具体的实现是Entities、Value Obiect、Services、DomainEvents、Factories、Repositories。而BoundedContext、Aggregate是抽象的概念。

Repositories

代表的是数据操作的资源和方法。比如说:订单信息最终还是要落库的,那么就会涉及到数据库操作那么就需要一个数据库操作的对象。让领域不关心数据的操作。

1.4UML(统一语言)

f30ca723f76ef9bc8b341e541ed6c615.png

(看字面意思就能懂的直接略过...)

组合:两个类的对象生命周期是关联的。

聚合:其他业务也可能包含同样的对象。

1.5 实践

COLA(COLA是阿里巴巴基于领域模型实现的一套服务端的框架)

2a1ab14c97ea652c07621e76fdb7d57e.png

1.6 Specification introduction(规范介绍)

121a8562bc12b99bdcc794fba059fd49.png

1.7GIT Manager(Git代码库版本管理)

5816d34e76b3f3f7f159ada18ab46ec6.png

1.8Test(测试环节)

cbaf0e52d49515ed1b91e3b7b460ab5a.png

单元测试:主要测试的是业务领域模型的逻辑。为什么要测试它呢?因为在做的时候我们的领域是不需要数据的,只要测试通过表示系统的关键业务没有出问题。

性能测试:根据在设计系统的时候,需要设置指标比如系统支撑的最大上限是多少,检测是否满足性能指标。性能测试的前提是在一定的资源下去做的,如果不断的增加服务器数量也是能达到性能指标的。

功能测试:大部分项目中的常见的测试,通过测试用例来验证功能是否可用。还有集成测试和回归测试。

2.Ref

https://domainstorytelling.org/#dst-ddd

https://www.wps.de/modeler/index.html

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

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

相关文章

Delphi实现的透明阴影以及蒙版效果菜单

QQ2010的皮肤控件目前实现了一部分,看到有些软件的菜单,都有阴影,透明等效果,于是开始重新实现菜单控件,QQ2009版的菜单控件,是自己从TComponent继承了完全模拟实现的一个菜单,虽然实现了菜单控…

cortana搜索框_如何在Windows 10任务栏上隐藏Cortana搜索框

cortana搜索框One of the most talked about features in the latest version of Windows 10 was the Cortana personal assistant that is integrated directly into the taskbar. But what if you don’t want to waste all that taskbar space? 最新版本的Windows 10中最受…

Kotlin 基础 - 数据类型

一、Boolean 类型 Boolean 值有两个值,分别为 true 或 false。多数情况下,Kotlin 中的 Boolean 相当于 Java 中的基本类型 boolean,只有在必要的情况下才会装箱成为 Java 中的装箱类型 Boolean。这一切都是交由编译器来完成,我们无…

微软公布Entity Framework 8.0规划

微软.NET团队在博客上公布了有关 Entity Framework Core 8.0(也称为 EF Core 8 或 EF8)的未来规划。EF Core 8 是 EF Core 7 之后的下一个版本,这将是一个长期支持版本;计划于 2023 年 11 月与 .NET 8 同时发布。该公司表示&#…

roku能不能安装软件_如何阻止假期更改Roku主题

roku能不能安装软件Wondering why your Roku looks…different? Roku occasionally changes the background for its millions of users, something they call a “featured theme.” 想知道为什么您的Roku看起来...不同吗? Roku偶尔会改变其数百万用户的背景&…

助力AIoT,雅观科技发布空间智能化操作系统

雷锋网(公众号:雷锋网)消息,3月14日,雅观科技在上海举办了“「AI」悟及物 「柔」生万屋”2019雅观科技新品发布会,发布了空间智能化操作系统Akeeta、空间智能化柔性服务技术中台Matrix,以及基于两者开发的雅观智慧社区…

如何在Windows 10的地图应用程序中获取离线地图

If you know you’re going to be using your PC in a location without an Internet connection, and you need access to maps, you can download maps for specific areas in the “Maps” app in Windows 10 and use them offline. 如果您知道要在没有Internet连接的地方使…

XenApp_XenDesktop_7.6实战篇之八:申请及导入许可证

1. 申请许可证 Citrix XenApp_XenDesktop7.6和XenServer 6.5申请许可证的步骤是一致的,由于之前我已经申请过XenApp_XenDesktop的许可证,本次以XenServer6.5的许可证申请为例。 1.1 在申请试用或购买Citrix产品时,收到相应的邮件&#xff0…

Windows 11的记事本将获得类似浏览器的标签功能

Windows 11已经向全世界的客户推出,自从它问世以来已经收到各种有趣的更新。例如,Windows 11的22H2版本(操作系统的第一个大更新)为文件资源管理器添加了标签,启用了任务栏的拖放支持,以及更多。Windows-11…

译⽂:Top Three Use Cases for Dapr and Kubernetes

有关译者:陈东海(seachen),⽬前就职于腾讯,同时在社区也是⼀名Dapr Member.导语:在SDLC(Software Development Lifecycle软件开发⽣命周期中),绝⼤多数CNCF项⽬都是专注于软件开发的中后期阶段,特别是运维和…

平视相机svo开源项目_什么是平视显示器(HUD),我应该得到一个吗?

平视相机svo开源项目In a world full of augmented reality snowboard goggles and Google Glass, it seems only fair that our cars get to enjoy some of the same treatment. Heads-up displays, or “HUDs” as they’re better known, are a new type of add-on for cons…

react项目打包后路径找不到,项目打开后页面空白的问题

使用 npm install -g create-react-app快速生成项目脚手架打包后出现资源找不到的路径问题: 解决办法:在package.json设置homepage 转载于:https://www.cnblogs.com/lan-cheng/p/10541606.html

ios 拍照 实现 连拍_如何在iOS设备上使用连拍模式拍照

ios 拍照 实现 连拍We’re sure you’ve tried to capture that perfect moment with your camera and you’re just a tad too late or too early and you miss it. If you own an iPhone or iPad, you can use burst mode and never miss that perfect shot again. 我们确定您…

路由热备份(HSRP)DynamipsGUI小试牛刀

——好久不见啊,大家最近过的还好吗?——学而不思则罔,思而不学则殆。好了,既然已经踏上了CCNP之旅,那就和大家一起分享一下学习HSRP的体会吧——在CCNA中我们设计网络的目的主要是——通!到了CCNP&#xf…

WPF 如何实现简单放大镜

WPF 如何实现简单放大镜控件名:Magnifier作 者:WPFDevelopersOrg - 驚鏵原文链接[1]:https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用.NET40;Visual Studio 2019;实现此功能需要用到 VisualBrush ,放大镜…

input 禁用智能提示_如何在智能手机上禁用紧急警报

input 禁用智能提示AMBER and emergency alerts occur when there’s a child abduction or there’s an important event such as a severe weather alert (tornado warning) that local governments needs to make people aware of. While we don’t recommend disabling the…

laravel中使用的PDF扩展包——laravel-dompdf和laravel-snappy

这两天项目中需要将HTML页面转换为PDF文件方便打印,我在网上搜了很多资料。先后尝试了laravel-dompdf和laravel-snappy两种扩展包,个人感觉laravel-snappy比较好用。 一、使用laravel-dompdf扩展包 1、安装扩展包 我们通过composer来安装 composer requi…

使用jenkins进行项目的自动构建部署

jenkins 简介 Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括:持续的软件版本发布/测试项目和监控外部调用执行的工作。 官网地址地址: https://jenkins.io 下载安装启动 CentOS 下用yum进行安装启动 …

如何删除Apple Music中的连接功能

Love Apple Music, but tired of the intrusive Connect feature taking up space on your favorite artist’s page? Well, don’t worry, because getting “dis-Connected” is just a matter of changing a few simple settings in your iPhone or iPad running iOS 8.0 o…