《实现领域驱动设计》

DDD入门

1.1 DDD是什么?

DDD是一种软件开发方法

  • DDD将领域专家和开发人员聚集到一起,开发的软件能够反映出领域专家的思维模型。目标是:交付最具业务价值的软件。
  • DDD关注业务战略:指引我们如何实现面向服务架构(service-oriented architecture)或者业务驱动(business-driven architecture)架构。
  • 使用战术设计建模工具:这些战术设计工具使开发人员能够按照领域专家的思维模型开发软件。保证成功地交付真正的业务价值。

1.2 为什么我们需要DDD?

  • 使领域专家和开发者在一起工作,这样开发的软件能够准确地传达业务规则。
  • "准确传达业务规则"意思是说:此时的软件就像是领域专家是编码人员时所开发出来的一样。
  • 可以帮助业务人员自我提高。在DDD中,每个人都在学习,同时每个人又是知识的贡献者。
  • 关键在于对于知识的集中,确保软件知识并不只是掌握在少数人手中。
  • 在领域专家、开发者和软件本身之间不存在"翻译"
  • 设计就是代码,代码就是设计
  • DDD提供了战略设计和战术设计两种方式。
    战略设计:帮助我们理解哪些投入是最重要的;
    战术设计:帮助我们创建DDD模型中各个部件。

1.3 如何DDD?

通用语言、限界上下文(Bounded Context)同时构成了DDD的两大支柱,并且它们是相辅相成的。

通用语言
通用语言是团队共享的语言。领域专家和开发者使用相同的通用语言进行交流。事实上,团队中每个人都使用相同的通用语言。不管你再团队中的角色如何,只要你是团队的一员,都将使用通用语言。团队成员通过讨论、参考资料、引用标准、查阅字典等对通用语言进行改进。有时我们发现,有些我们曾经认为能很好表达业务的词汇不再适用了,而另外的一些词汇具有更好的效果。

1.4 使用DDD的业务价值

不管使用什么技术,我们的目的都是提供业务价值。

我们可以将DDD的业务价值大致总结为以下几点:

1.你获得了一个非常有用的领域模型
2.你的业务得到了更准确的定义和理解
3.领域专家可以为软件设计做出贡献
4.更好的用户体验
5.清晰的模型边界
6.更好的企业架构
7.敏捷、选代式和持续建模
8.使用战略和战术新工具

1.5 实施DDD所面临的挑战

  • 为创建通用语言腾出时间和精力
    使用DDD最大的挑战之一便是:我们需要花费大量的时间和精力来思考业务领域,研究概念和术语,并且和领域专家交流,以发现、捕捉和改进通用语言。如果你想完全采用DDD来最大化业务价值,你需要做出很多努力,并且花费很多时间。
  • 持续地将领域专家引入项目
    要将领域专家引入你的项目恐怕也不是一件易事。但是不管有多么困难,这是你必须做的。如果你连一个领域专家都找不到,那么你根本无法对一个领域有深入的理解。
  • 改变开发者对领域的思考方式
    多数开发者在采用DDD时都需要转变自己思考问题的方式。作为开发者,我们都是技术思想者,技术实现对于我们来说并不是什么难事。我并不是说技术地思考不好,只是说有时少从技术层面去思考会更好。这么多年来,我们都习惯了单从技术层面完成软件开发,那么现在,是时候考虑一种新的思考方式了。为你的业务领域开发一门通用语言便是一个好的出发点。

2 领域、子域、界限上下文

由于“领域模型”包含了“领域”这个词,我们可能会认为应该为整个业务系统创建一个单一的、内聚的、全功能式的模型。然而,这并不是我们使用DDD的目标。正好相反,在DDD中,一个领域被分为若干子域,领域模型在限界上下文中完成开发。事实上,在开发一个领域模型时,我们关注的通常只是这个业务系统的某个方面。
工作中的子域和限界上下文
在这里插入图片描述

将关注点放在核心域上
在这里插入图片描述
图2.2上半部分的领域边界,你会看到一个叫核心域的子域。
对于核心域,它是整个业务领域的一部分,也是业务成功的主要促成因素。从战略层面上讲,企业应该在核心域上胜人一筹。我们应该给予核心域最高的优先级、最资深的领域专家和最优秀的开发团队。在实施DDD的过程中,你将主要关注于核心域。

图2.2中还展示了另外两种子域:支撑子域和通用子域
有时,我们会创建或者购买某个限界上下文来支撑我们的业务。如果这样的限界上下文对应着业务的某些重要方面,但却不是核心,那么它便是一个支撑子域
创建支撑子域的原因在于它们专注于业务的某个方面,否则,如果一个子域被用于整个业务系统,那么这个子域便是通用子域
我们并不能说支撑子域和通用子域是不重要的,它们是重要的,只是我们对它们的要求并不像核心域那么高。

2.1 战略设计为什么重要

2.2 现实世界中领域和子域

领域中还同时存在问题空间(problem space)和解决方案空间(solution space)在问题空间中,我们思考的是业务所面临的挑战,而在解决方案空间中,我们思考如何实现软件以解决这些业务挑战。
以下是如何将这两者应用到我们已经学过的知识中:

  • 问题空间是领域的一部分,对问题空间的开发将产生一个新的核心域。
    对问题空间的评估应该同时考虑已有子域和额外所需子域。因此,问题空间是核心域和其他子域的组合。问题空间中的子域通常随着项目的不同而不同,他们各自关注于当前的业务问题,这使得子域对于问题空间的评估非常有用。子域允许我们快速地浏览领域中的各个方面,这些方面对于解决特定的问题是必要的。
  • 解决方案空间包括一个或多个限界上下文,即一组特定的软件模型。
    这是因为限界上下文即是一个特定的解决方案,它通过软件的方式来实现解决方案。

2.3 理解限界上下文

在很多情况下在不同模型中存在名字相同或相近的对象,但是它们的意思却不同。当模型被一个显式的边界所包围时,其中每个概念的含义便是确定的了。因此,限界上下文主要是一个语义上的边界,我们应该通过这一点来衡量对一个限界上下文的使用正确与否。

在这里插入图片描述

不同限界上下文中的Account对象具有完全不同的含义
银行上下文:账户表示一个客户在银行的存款支票账户和储蓄账户
状态,并记录每次交易信息。
文学上下文:账户表示用文字记录的在一段时间之内发生的一系列事件。

在通常情况下,我们所面对的都是一些区别甚小的概念定义。原因在于:在一个上下文中,团队通常根据通用语言来命名某个概念。我们并不会随意地命名一个概念以刻意地保持与其他上下文的不同。

比如两个银行上下文,一个用于支票账户另一个用于储蓄账户。在支票上下文(Checking
Context)中我们不必使用支票账户(CheckingAccount);在储蓄上下文(Saving Context)中我们也不必使用储蓄账户(SavingAccount)。两个概念都可以使用账户(Account)来表示因为限界上下文已经对此做了区分。当然,我们并没有规定不能使用更具体的名字这只是团队自己的选择而已。

当需要集成时,我们必须在不同的限界上下文之间进行概念映射。
限界上下文不仅仅只包含模型
一个限界上下文并不是只包含领域模型。诚然,模型是限界上下文的主要“公民”。但是,限界上下文并不只局限于容纳模型,它通常标定了一个系统、一个应用程序或者一种业务服务”。有时,限界上下文所包含的内容可能比较少,比如,一个通用子域便可以只包含领域模型。

限界上下文主要用来封装通用语言和领域对象,但同时它也包含了那些为领域模型提供交互手段和辅助功能的内容。需要注意的是,对于架构中的每个组件,我们都应该将其放在适当的地方。
限界上下文的大小
限界上下文应该足够大,以能够表达它所对应的整套通用语言。

核心领域之外的概念不应该包含在限界上下文中。如果一个概念不属于你的通用语言,那么一开始你就不应该将其引入到模型中。

与技术组件保持一致
将限界上下文想成是技术组件并无大碍,只是我们需要记住:技术组件并不能定义限界上下文。
在这里插入图片描述
让我们来看看示例DDD项目中的这3个限界上下文。他们分别是协作上下文身份与访问上下文敏捷项目管理上下文

协作上下文
在这里插入图片描述
协作上下文的团队将所有与安全和权限相关的模块和类型从该上下文中移除,然后逐渐采用新的身份与访问上下文。

身份与访问上下文

现在,多数企业级应用程序都需要某种形式的安全和权限组件,这样的组件用以对用户进行认证和授权。正如我们在前面所分析的,一种幼稚的做法是将这样的组件嵌入到每一个离散的系统中,这将导致每一个系统都产生筒仓效应(siloeffect) .
在这里插入图片描述
当有我们关心的状态由于模型行为而发生改变时,系统将发布领域事件(8)。

敏捷项目管理上下文
在这里插入图片描述

3 上下文映射图

一个项目的上下文映射图(Context Map)可以用两种方式来表示比较容易的一种是画一个简单的框图来表示两个或多个限界上下文之间的映射关系。该框图表示了不同的限界上下文在解决方案空间中是如何通过集成相互关联的。另一种更详细的方式是通过限界上下文集成的源代码实现来表示。

3.1 上下文映射图为什么重要

在这里插入图片描述
你的映射图可以使你了解到映射图的内部,并且可以指明在哪些地方需要与其他团队进行交流。尽早绘制上下文映射图,这样可以迫使你仔细思考你的项目和你所依赖项目之间的关系。

绘制上下文映射图
上下文映射图并不是一种企业架构,也不是系统拓扑图。但是,它可以用于高层次的架构分析,指出诸如集成瓶颈之类的架构不足。上下文映射图展现了一种组织动态能力(organizational dynamic)它可以帮助我们识别出有碍项目进展的一些管理问题。
限界上下文之间的关系

  • 合作关系(Partnership)
  • 共享内核(SharedKernel)
    对模型和代码的共享将产生一种紧密的依赖性。
    对于设计来说,这种依赖性可好可坏。我们需要为共享的部分模型指定一个显式的边界,并保持共享内核的小型化。
  • 客户方-供应方开发(Customer-Supplier Development)
    当两个团队处于一种上游-下游关系时,上游团队可能独立于下游团队完成开发,此时下游团队的开发可能会受到很大的影响。
  • 遵奉者(Conformist)
    在存在上游-下游关系的两个团队中如果上游团队已经没有动力提供下游团队之所需,下游团队便孤军无助了。
  • 防腐层(Anticorruption Layer)
    防腐层通过已有的接口与其他系统交互,而其他系统只需要做很小的修改,甚至无须修改。在防腐层内部,它在你自己的模型和他方模型之间进行翻译转换。
  • 开放主机服务(Open Host Service)
    定义一种协议,让你的子系统通过该协议来访问你的服务。
  • 发布语言(Published Language)
    在两个限界上下文之间翻译模型需要一种公用的语言。
  • 另谋他路(SeparateWay)
    在确定需求时我们应该做到坚决彻底。如果两套功能没有显著的关系,那么它们是可以被完全解耦的。
  • 大泥球(Big Ballof Mud)
    当我们检查已有系统时经常会发现系统中存在混杂在一起的模型,它们之间的边界是非常模糊的。此时你应该为整个系统绘制一个边界,然后将其归纳在大泥球范围之列。
映射3个示例限界上下文

在这里插入图片描述
身份与访问上下文位于最上游它对协作上下文和敏捷项目管理上下文均会产生影响。同时,协作上下文又是敏捷项目管理上下文的上游,因为后者的模型依赖于前者的模型和服务。

所有下游系统的连接框都标以ACL,即防腐层。对于它们的技术实现将在集成限界上下文(13)中讲到。

协作上下文
协作上下文通过传统的类似于RPC的方式获取外部资源。协作上下文并不会永久性地记录下从身份与访问上下文中获取来的数据而是在每次需要数据时重新向远程系统发出请求。
在这里插入图片描述
敏捷项目管理上下文
为了达到比RPC更高的自治性,敏捷项目管理上下文的团队将尽量限制对RPC的使用,此时他们可以选择异步请求,或者事件处理等方式。

DDD的做法是:在本地创建一些由外部模型翻译而成的领域对象,这些对象保留着本地模型所需的最小状态集。为了初始化这些对象,我们只需要有限的RPC调用或REST请求。然而,要与远程模型保持同步,最好的方式是在远程系统中采用面向消息的通知(notification)机制。消息通知可以通过服务总线进行发布也可以采用消息队列或者REST。
在这里插入图片描述

和身份与访问上下文集成
在这里插入图片描述
敏捷项目管理上下文在本地有DiscussionService和SchedulingService,它们是领域服务,用于管理协作系统中的讨论和日历条目

4 架构

DDD的一大好处便是它并不需要使用特定的架构。由于核心域(2)位于限界上下文(2)中我们可以在整个系统中使用多种风格的架构有些架构包围着领域模型,能够全局性地影响系统,而有些架构则满足了某些特定的需求。我们的目标是选择适合于自己的架构和架构模式。

4.2 分层

分层架构模式[Buschmannetal被认为是所有架构的始祖它支持N层架构系统,因此被广泛地应用于Web、企业级应用和桌面应用。在这种架构中,我们将一个应用程序或者系统分为不同的层次。
图4.1所示为一个典型的DDD系统所采用的传统分层架构,其中核心域只位于架构中的其中一层其上为用户界面层(User Interface)和应用层(ApplicationLayer),其下是基础设施层(Infrastructure Layer)。

在这里插入图片描述

4.3 六边形架构 (端口与适配器)

4.4 面向服务架构SOA

4.5 REST

4.6 命令和查询职责分离

CORS

4.7 事件驱动架构

4.8 数据网织和基于网格的分布式计算

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

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

相关文章

Unity报错:Microsoft Visual C# Compiler version

Unity报错:Microsoft Visual C# Compiler version 问题解决方案总结 问题 Microsoft Visual C# Compiler version 2.9.1.65535 (9d34608e) Copyright © Microsoft Corporation 切换版本或者使用老项目的时候可能会出现这个报错,这个报错就是项目设置的问题 …

AI新能量!FortiGate NGFW面向数据中心全面集成FortiGuard AI 安全服务

企业IT技术正在以惊人的速度发展,转型最大的领域之一是下一代防火墙(NGFW)市场。如今,混合云、多云、边缘等多种基础设施形态共存,已经成为大部分企业的常态,不断扩张的攻击面需要不同形态防火墙的安全防护…

uniapp 单选框以及多选框样式更改

radio以及checkbox默认样式不符合自身需求时,根据自身需求更改样式,以下是自身的示例: 单选: 多选: 由于uniapp自身包含了一套默认的样式,所以如果不想全局更改只想在某个单据页面使用的话,就…

RDMA概览

RDMA(Remote Direct Memory Access,远程直接内存访问),指能够访问(读写)远程机器的内存。有多种支持RDMA的网络协议,包括:Infiniband、RoCE和iWAPP。具体的API定义包含在内核文件linux/include/rdma/ib_verbs.h reference: 【精选…

Pytorch--3.使用CNN和LSTM对数据进行预测

这个系列前面的文章我们学会了使用全连接层来做简单的回归任务,但是在现实情况里,我们不仅需要做回归,可能还需要做预测工作。同时,我们的数据可能在时空上有着联系,但是简单的全连接层并不能满足我们的需求&#xff0…

Android---StartActivity启动过程

在手机桌面应用中点击某一个 icon 之后,最终是通过 startActivity 去打开某一个 Activity 页面。我们知道,Android 中的一个 APP 就相当于一个进程。所以,startActivity 操作中还需要判断,目标 Activity 的进程是否已经创建。如果…

米尔AM62x核心板助力新一代工业4.0升级

米尔AM62x核心板 续写AM335x经典 在过去的十几年中,TI Sitara系列推出了很多优秀的处理器,其中在工业、电力、医疗等领域有着广泛应用的AM335x系列处理器,引领工业市场从MCU向MPU演进,帮助产业界从ARM9迅速迁移至高性能Cortex-A…

Spring Authorization Server 1.1 扩展实现 OAuth2 密码模式与 Spring Cloud 的整合实战

目录 前言无图无真相创建数据库授权服务器maven 依赖application.yml授权服务器配置AuthorizationServierConfigDefaultSecutiryConfig 密码模式扩展PasswordAuthenticationTokenPasswordAuthenticationConverterPasswordAuthenticationProvider JWT 自定义字段自定义认证响应认…

【ARM Trace32(劳特巴赫) 使用介绍 2 -- Trace32 cmm 脚本基本语法及常用命令】

文章目录 Trace32 CMM 概述1.1 Trace32 系统命令 SYStem1.1.1 Trace32 SYStem.CONFIG1.1.2 SYStem.MemAccess1.1.3 SYStem.Mode1.1.3.1 TRST-Resets the JTAG TAP controller and the CPU internal debug logic1.1.3.2 SRST- Resets the CPU core and peripherals 1.2 Trace32 …

【Linux】解决缓存锁问题:无法获得锁 /var/lib/dpkg/lock-frontend

今天在运行apt-get update更新软件包后,突然发现安装新的软件出现了这个报错:正在等待缓存锁:无法获得锁 /var/lib/dpkg/lock-frontend。锁正由进程 1855(unattended-upgr)持有。如图。 这个错误通常是由于其他进程正在…

“从部署到优化,打造高效会议管理系统“

目录 引言一、部署单机项目 - 会议OA1.1 硬件和软件环境准备1.2 检查项目1.3 系统部署1.后端部署 二、部署前后端分离项目 - SPA项目后端部署2.前端部署 总结 引言 在现代化办公环境中,会议是组织沟通、决策和合作的重要方式之一。为了提高会议的效率和质量&#x…

Win11安装ise14.7~不需要虚拟机了~

之前一直无法在win11上安装ise14.7,网上搜索也无果,所有一直vmware虚拟机使用。直到最近看了水木上jesce的回复,试了下果然可以直接安装使用的。 步骤如下即可: 1.安装时切勿勾选最后一项,Enable WebTalk to send so…

2023 10月最新Vmd 下载安装教程,WindowsLinux

文章目录 下载Vmdwindows版本安装LINUX版本安装 下载Vmd 谷歌搜索VMD 点击左下角download VMD 可选择对应版本 注:点击后会出现输入用户名和密码,由于我已注册,界面不见了,所以直接描述一下。 输入用户名和密码然后会出现让登记…

SLAM从入门到精通(lidar的运动畸变矫正)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面我们说过,很多时候传感器的数据并不能直接拿过来使用。这里面除了噪声的原因之外,另外一部分原因就是传感器数据本身也…

算法通关村第三关|青铜|线性表数组热身

1.线性表 1.1 线性表 线性表就是具有相同特征数据元素的一个有限序列。 1.2 数组存储元素的初始化 数组初始化时必须对从前向后的连续空间初始化,不可以出现空缺的情况。写 0 也是初始化,也要从前向后写。 2.热身-单调数组 判断是否为单调数组&am…

设置Ubuntu 20.04的静态IP地址(wifi模式下)

一、引言 自己家用的Ubuntu的,重启后ip地址经常会改变,这个时候就需要我们手动配置静态IP了。 二、优点 给Ubuntu设置一个静态IP地址有以下几个好处: 持久性:静态IP地址是固定不变的,与设备的MAC地址绑定。这意味着…

一、【Photoshop如何根据不同类型图像抠图】

文章目录 前言图形结构1、规则图形2、不规则图形 图形颜色1、轮廓清晰2、颜色分明 前言 当我们有抠图需求的时候,不要一开始就想着我怎么去把它抠出来,首先应该分析图形的特点,然后再去选取合适的工具,这样才可以做到事半功倍&am…

经典卷积神经网络 - NIN

网络中的网络,NIN。 AlexNet和VGG都是先由卷积层构成的模块充分抽取空间特征,再由全连接层构成的模块来输出分类结果。但是其中的全连接层的参数量过于巨大,因此NiN提出用1*1卷积代替全连接层,串联多个由卷积层和“全连接”层构成…

电脑定时关机

电脑定时关机 1.右键 管理 2. 3. 4. 5. shutdown.exe/s /f /t 06.点击完成就好了 7.这里面可以 看到定时任务和启动 右键有运行 结束 禁用

Flask 上传文件,requests通过接口上传文件

这是一个使用 Flask 框架实现文件上传功能的示例代码。该代码定义了两个路由: /upload:处理文件上传请求。在该路由中,我们首先从请求中获取上传的文件,然后将文件保存到本地磁盘上,并返回一个字符串表示上传成功。 /…