领域驱动设计学习之路—DDD的原则与实践

本文是我学习Scott Millett & Nick Tune编著的《领域驱动设计模式、原理与实践》一书的学习笔记,一共会分为4个部分如下,此文为第1部分:

领域驱动设计的原则与实践战略模式:在有界上下文之间通信战术模式:创建有效的领域模型有效应用程序的设计模式

一、什么是领域驱动设计

640?wx_fmt=png

  脑图浏览:https://www.processon.com/view/5cb49b14e4b0a13c9de1042d#map

  这一章主要介绍了DDD是什么,强调DDD是一种开发思想体系,它是模式(战略模式、战术模式)、原则和实践的集合,可以被应用到软件设计中以管理复杂性

  DDD并非一种模式语言,它是专注于交付的一种协作思想体系,其中通信起核心作用,而要高效通信,就需要使用公共语言。

  DDD会将侧重点放在以下几个方面:

  • 核心领域

  • 协作

  • 与领域专家探讨

  • 实验研究以生成更有用的模型

  • 对各种上下文的理解

  更为重要的是,不要认为DDD是一套框架,DDD也不是银弹或灵丹妙药,不可在项目中小题大做!

  下图展示了一个演进的领域驱动设计过程:

640?wx_fmt=png

From:张逸《领域驱动战略设计实践》课程

  这里摘抄一段张逸老师在《领域驱动战略设计实践》课程中的话:

  面对客户的业务需求,由领域专家与开发团队展开充分的交流,经过需求分析与知识提炼,以获得清晰的问题域。通过对问题域进行分析和建模,识别限界上下文,利用它划分相对独立的领域,再通过上下文映射建立它们之间的关系,辅以分层架构与六边形架构划分系统的逻辑边界与物理边界,界定领域与技术之间的界限。之后,进入战术设计阶段,深入到限界上下文内对领域进行建模,并以领域模型指导程序设计与编码实现。若在实现过程中,发现领域模型存在重复、错位或缺失时,再进而对已有模型进行重构,甚至重新划分限界上下文。

  两个不同阶段的设计目标是保持一致的,它们是一个连贯的过程,彼此之间又相互指导与规范,并最终保证一个有效的领域模型和一个富有表达力的实现同时演进。

二、提炼问题域

640?wx_fmt=png

  脑图地址:https://www.processon.com/view/5cb5e474e4b0841b84327187#map

  这一章主要介绍了什么是知识提炼,知识提炼是一个持续协作达成共识以创建有用模型的过程,而如何实践好这个过程,介绍了一些最佳实践:比如专注于最有意思的对话、从用例开始、提出有力的问题等等。

  而对于不需要构建新模型的人来说,研究现有模型也是有技巧的,个人感触最深的就是要真正理解意图,也就是不要盲从于客户的需求,因为这个需求很可能并不能真正地解决问题和创造价值,往往需要更深层次地理解隐含的愿景并且能够认识到业务到底试图达到什么。影响地图和业务模型是两个经典的实践方法,书中的例子在线运动装备运营商的业务模型图也比较经典。

三、专注于核心领域

640?wx_fmt=png

  脑图浏览地址:https://www.processon.com/view/5cba8957e4b059e20a0068c8#map

  这一章主要介绍了核心领域,在一个大的问题空间中会同时存在很多的小问题域,而这些小问题域往往只有少部分是核心领域,其他的可能都是通用域和支撑域。核心域是我们软件的根本竞争力所在,因此也可以说是我们编写软件的原因。拿一个在线拍卖网站来说,可以见下图所示划分了核心域、支撑域和通用域:

640?wx_fmt=png

  对于核心域,我们需要配备最好的开发人员专注于此。对于支撑域,我们可以外包开发或者配备初级开发人员,但是要确保支撑域中的模型足够好。而对于通用域,如果可以,我们可以寻求购买现成解决方案。

四、模型驱动设计

640?wx_fmt=png

  脑图浏览地址:https://www.processon.com/view/5cbaa844e4b01941c8b441d2

  这一章主要介绍了模型驱动设计和通用语言的重要性,模型驱动设计是将分析模型(业务模型)绑定到代码实现模型并确保这两个模型保持协同并可用的过程。

  模型驱动设计专注于实现以及对于初始模型可能需要修改的约束,领域驱动设计则专注于语言、协作和领域知识,他们是一个彼此互补的关系。而要实现协作,就需要使用通用语言,借助通用语言可以将分析模型和代码模型绑定在一起,并最终实现团队建模。实践UL是一个持续的过程,多个迭代后会不断对UL进行验证和改进,以便实现更好的协作。

  由于时间和精力都有限,只有仅仅为核心域应用模型驱动设计和创建UL才能带来最大的价值,而不需要将这些实践应用到整个应用程序之中。

五、领域模型实现模式

640?wx_fmt=png

  脑图浏览地址:https://www.processon.com/view/5cbab6c5e4b06bcc13844497

  这一章主要介绍了领域层的概念及作用,下图展示领域层在在整个应用程序代码中的位置,领域层的最大作用就在于隔离领域模型的复杂性和应用程序的技术复杂性。

  640?wx_fmt=png

  在领域建模时可以遵循的设计模式,Martin Fowler在《企业应用架构模式》一书中提出了以下几种:

  • 领域模型模式:适用于复杂问题域,领域中的概念被封装为数据和行为的对象

  • 事务脚本模式:组织所有的领域逻辑来满足业务事务或用例

  • 表模块模式:代表着以对象形式建模的数据,数据驱动

  • 活动记录模式:类似表模块,数据驱动,关注表中的行而非表本身

  • 贫血模式:类似领域模型,不包含任何行为,纯粹的一个对象状态模型,需要一个单独的服务类来实现行为

六、使用有界上下文维护领域模型的完整性

640?wx_fmt=png

  脑图浏览地址:https://www.processon.com/view/5cbad3dee4b09a3e45a3fbc6

  通常情况下,尝试将单个模型用于复杂问题域通常会导致代码变成大泥球,而且会增加团队之间的协作成本并降低交付业务价值的效率。有界上下文就是划分和破除这种大模型的有效方式,一个有界上下文就是一个语言边界,它可以隔离模型以避免领域术语在不同上下文中的歧义。而我们常常提到的微服务,个人感觉更像是有界上下文的一种技术实现途径之一,有界上下文中具有较高的自主性,拥有从展现层、领域逻辑层再到持久化层的完整代码堆栈,正应对了我们的每一个微服务的应用程序,也具有较高的独立性,拥有自己的数据库和一套完成的垂直切片的架构模式。

  书中还提到一个重要的观点,那就是“并非所有有界上下文都共享相同的架构模式”,换句话说就是可以将不同的架构模式应用到不同的有界上下文中。想想这年来的企业应用架构模式的发展,已经从单一的架构风格发展为了混合式的架构风格了,就微软的大DEMO项目eShopOnContainers而言,也具有多种架构风格(简单的数据驱动CRUD+简化的分层DDD等),如下图所示:

640?wx_fmt=png

  因此,我们也不应该局限在某一种或者两种架构模式上,而是应该量身应用,没有复杂性业务逻辑的微服务,那就应该KISS(Keep It Simple & Stupid),否则就可以考虑DDD。

七、上下文映射

640?wx_fmt=png

  脑图浏览地址:https://www.processon.com/view/5cbc3240e4b0bab909613768

  上下文映射用来捕获各个有界上下文之间的技术与组织关系,它最大的作用就是保持模型的完整性。张逸老师在《领域驱动战略设计实践》课程中提到,在战略设计阶段,针对问题域,通过引入限界上下文和上下文映射可以对问题域进行合理的分解,识别出核心领域和子领域,并确定领域的边界以及他们之间的关系,从而维持模型的完整性。

  限界上下文不仅局限于对领域模型的控制,而在于分离关注点之后,使得整个上下文可以成为独立部署的设计单元,这就是我们非常熟悉的“微服务”的概念;而上下文映射的诸多模式则对应了微服务之间的协作。  

八、应用程序架构

640?wx_fmt=png

  脑图浏览地址:https://www.processon.com/view/5cc1cbe4e4b0841b84400fc9

  这一章讨论了应用程序架构、服务和客户端,唯一记住的只有一句:“DDD不需要特殊的架构,只要是能将技术问题与业务问题分离的架构即可”。

九、团队开始应用DDD通常会遇到的问题

640?wx_fmt=png

  脑图浏览地址:https://www.processon.com/view/5cc46afbe4b08b66b9bd9513

  DDD的战术模式虽然可以指导我们创建有效领域模型,但这并非DDD的真正价值所在。因为,DDD其实并非编码这么简单,与领域专家的协作以进行知识提炼,以及在通用语言中表述的问题域达成共识才是DDD的支柱。

  在现实中,团队在应用DDD时通常会低估应用DDD的成本,应用DDD需要一个愿意学习该领域的聪明专注的团队,还需要领域专家的参与,没有他们,团队就无法揭示更深层的见解。

十、应用DDD的原则、实践与模式

640?wx_fmt=png

  脑图浏览地址:https://www.processon.com/view/5cc5568be4b059e20a0bc1e1

  DDD不是灵丹妙药,更不是“银弹”,张逸老师说道:请事先降低对领域驱动设计的不合现实的期望,要学会运用设计原则去解决问题,而非所谓的“设计规范”。更为重要的是,仅仅在需要时应用DDD原则,不要将其用作解决所有问题的工具。

  总体来说,这一章比较高屋建瓴,总结性的内容偏多,但对于没有多少实战经验的人来说,阅读完不会有太深刻的印象。不过,这并不影响,后续就是战略设计和战术设计的部分了,相信会随着学习的深入,再反过来看这些原则和实践会有更多的认识。

参考资料

Scott Millett & Nick Tune,《领域驱动设计模式、原理与实践》

原文地址:https://www.cnblogs.com/edisonchou/p/edc_ddd_foundation_study_part1.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 
640?wx_fmt=jpeg

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

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

相关文章

.NET Core中使用Dapper操作Oracle存储过程最佳实践

为什么说是最佳实践呢?因为在实际开发中踩坑了,而且发现网上大多数文章给出的解决方法都不能很好地解决问题。尤其是在获取类型为OracleDbType.RefCursor,输出为:ParameterDirection.Output数据的时候。网上千篇一律的说写一个Ora…

CanalSharp.AspNetCore v0.0.4-支持输出到MongoDB

一、多样输出支持CanalSharp.AspNetCore是一个基于CanalSharp的适用于ASP.NET Core的一个后台任务组件,它可以随着ASP.NET Core实例的启动而启动,目前采用轮询的方式对Canal Server进行监听,获得MySql行更改(RowChange&#xff09…

CF1039C Network Safety

CF1039C Network Safety 题意: 题解: 如果我们同时选中a,b两个点,无论异或什么值,都不会影响图的安全性,因为图本来就是安全的 破坏图的安全性只有一种情况,那就是选了a,没选b&…

使用Jenkins来实现内部的持续集成流程(下)

目录配置项目构建添加任务添加源代码地址和登录凭据添加构建触发器 TFS添加WebHook 添加构建步骤后端UI API端 配置项目构建1添加任务2添加源代码地址和登录凭据添加源代码地址和登录凭证此图没有填写凭证时显示的错误点击Credential后面的添加 填写能访问源代码的用户名和密码…

.NET和Docker ,比翼双飞

DockerCon 2019本周将在旧金山举行 ,DockerCon 是从业者、贡献者、维护者、开发者和容器生态系统学习、网络和创新的一站式活动。 .NET 团队博客发布了《一起使用.NET和Docker - DockerCon 2019更新》:https://devblogs.microsoft.com/dotnet/using-net-…

Visible Lattice Points SPOJ - VLATTICE

Visible Lattice Points SPOJ - VLATTICE 题意&#xff1a; 有一个n∗n∗n的三维直角坐标空间&#xff0c;问从(0,0,0)看能看到几个点。 题解&#xff1a; 本题是二维的一个升级版&#xff0c;升级成三维 用莫比乌斯反演来做 代码&#xff1a; #include <bits/stdc.h…

使用ASP.NET Core开发GraphQL服务器 -- 极简预备知识(上)

为了介绍使用ASP.NET Core构建GraphQL服务器&#xff0c;本文需要介绍一下GraphQL&#xff0c;其实看官网的文档就行。什么是GraphQL&#xff1f;GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描…

使用 dotnet 命令行配合 vscode 完成一个完整 .NET 解决方案的编写和调试

如果你是开发个人项目&#xff0c;那就直接用 Visual Studio Community 版本吧&#xff0c;对个人免费&#xff0c;对小团体免费&#xff0c;不需要这么折腾。如果你是 Mac / Linux 用户&#xff0c;不想用 Visual Studio for Mac 版&#xff1b;或者不想用 Visual Studio for …

亲儿子 | Azure SignalR 服务现在支持 ASP.NET

点击上方蓝字关注“汪宇杰博客”文 / Zhidi译 / Edi Wang我们刚刚发布了支持ASP.NET的正式版 SignalR 服务 SDKMicrosoft.Azure.SignalR.AspNet v1.0.0Azure SignalR 服务是一种完全托管的用于实时消息传递的 Azure 服务。它是扩展 ASP.NET Core SignalR 应用程序的首选方法。但…

VS Code Remote 发布!开启远程开发新时代

今天&#xff08; 北京时间 2019 年 5 月 3 日 &#xff09;&#xff0c;在 PyCon 2019 大会上&#xff0c;微软发布了 VS Code Remote&#xff0c;开启了远程开发的新时代&#xff01;这次发布包含了三款核心的全新插件&#xff0c;它们可以帮助开发者在容器&#xff0c;物理或…

使用ASP.NET Core开发GraphQL服务器 -- 预备知识(下)

上一篇&#xff1a;使用ASP.NET Core开发GraphQL服务器 -- 极简预备知识(上)处理数据嵌套字段看例子&#xff1a;我想查看viewer下的repositories。注意里面的edges&#xff0c;一旦看到这个词&#xff0c;通常就表示有连接到某个数组的数据。在这里就是一个集合的repository。…

使用 Docker 在 Linux 上托管 ASP.NET Core 应用程序

说在前面在阅读本文之前&#xff0c;您必须对 Docker 的中涉及的基本概念以及常见命令有一定了解&#xff0c;本文侧重实战&#xff0c;不会对相关概念详述。同时请确保您本地开发机器已完成如下安装&#xff1a;Docker 18.06 或更高版本的 Docker 客户端.NET Core SDK 2.2 或更…

ICPC网络赛第二场G Limit

ICPC网络赛第二场G Limit 题意&#xff1a; 给你数组a和b&#xff0c;求解&#xff1a; 1≤n≤100000,−100≤ai,bi≤100,0≤t≤5.1≤n≤100000,−100≤a_{i},b_{i}≤100,0≤t≤5.1≤n≤100000,−100≤ai​,bi​≤100,0≤t≤5. 题解&#xff1a; 要用到洛必达来做&#xf…

[VSCode插件推荐] REST Client: 也许是比Postman更好的选择

在测试REST API的时候&#xff0c;想必大家都会有不同的工具选择。如果是基于CLI的话&#xff0c;大家应该会选择cURL。如果是GUI工具的话&#xff0c;相信很多人都会使用Postman。不过今天&#xff0c;笔者要推荐的是REST Client插件。也许&#xff0c;它是比Postman更好的选择…

.Net资讯 | 一大波开发者福利来了, 一份微软官方Github上发布的开源项目清单等你签收...

目录微软Github开源项目入口微软开源项目受欢迎程度排名Visual Studio CodeTypeScriptRxJS.NET Core 基础类库CNTKMicrosoft calculatorMonaco editorMS-DOSRedis windows版.NET Core CLR (公共语言运行时)ASP.NET CoreEntity Framework CorePowerShell如何在其中搜索自己需要的…

C#位运算实际作用之操作整型某一位

1.前言前几天写了两篇关于c#位运算的文章c#位运算基本概念与计算过程C#位运算实际运用在文中也提到了位运算的实际作用之一就是合并整型&#xff0c;当时引用了一个问题&#xff1a;C# 用两个short&#xff0c;一个int32拼成一个long型&#xff0c;高16位用short&#xff0c;中…

使用高性能Pipelines构建.NET通讯程序

.NET Standard支持一组新的API&#xff0c;System.Span, System.Memory&#xff0c;还有System.IO.Pipelines。这几个新的API极大了提升了.NET程序的效能&#xff0c;将来.NET很多基础API都会使用它们进行重写。Pipelines旨在解决.NET编写Socket通信程序时的很多困难&#xff0…

全球开发者的年度盛宴:微软全球开发者大会 Build 2019邀您一同加入

一年一度的微软全球开发者大会&#xff08;Build&#xff09;将于5月6日至8日在美国西雅图举办。本届大会将围绕全球当下的热门技术展开&#xff0c;包括人工智能、机器学习、容器、DevOps、物联网、混合现实以及Power Platforms等&#xff1b;微软热爱开发者、重视开发者&…

Oracle杀死Java EE:名正言顺转到.NET Core

Eclipse 基金会执行董事 Mike Milinkovich 昨日在博客发表了 Oracle 与 Eclipse 基金会之间关于 Java 商标谈判的结果 —— 双方的谈判最后以失败告终&#xff0c;Oracle 拒绝出让 Java 商标。Mike 在博客中还提及了 Eclipse 基金会和 Oracle 之间关于 Jakarta EE 的协议、Java…

程序员修神之路--redis做分布式锁可能不那么简单

点击上方“蓝字”带你去看小星星菜菜哥&#xff0c;复联四上映了&#xff0c;要不要一起去看看&#xff1f;又想骗我电影票&#xff0c;对不对&#xff1f;呵呵&#xff0c;想去看了叫我呀看来你工作不饱和呀哪有&#xff0c;这两天我刚基于redis写了一个分布式锁&#xff0c;很…