领域驱动设计(Domain-Driven Design DDD)——战略设计1

一、概述

        随着系统的增长,它会越来越复杂,当我们无法通过分析对象来理解系统的时候,就需要掌握一些操纵和理解大模型的技术了。

        最负雄心的企业欲实现一个涵盖所有业务、紧密集成的系统。因大型公司的业务模型巨大且复杂,很难把它作为一个整体来理解且难以管理。按传统做法,我们可以将其拆为较小的部分后组合。但问题在于,如何保证实现这种模块化的同时,不失去集成所具备的好处;从而使系统的不同部分能够进行互操作,以便协调各种业务操作。如果设计一个把所有概念都涵盖进来的单一领域模型,它将会非常笨拙,而且将会出现大量难以察觉的重复和矛盾。而如果用临时拼凑的接口把一组小的、各自不同的子系统集成到一起,又不具备解决企业级问题的能力,并且在每个集成点上都有可能出现不一致。通过采用系统的、不断演变的设计策略,就可以避免这两种极端问题。

        即使这种规模的系统中采用领域驱动设计方法,也不要脱离实现去开发模型。每个决策都必须对系统开发产生直接的影响,否则它就是无关的决策。战略设计原则必须指导设计决策,以便减少各个部分之间的互相依赖,在使设计意图更为清晰的同时而不失去关键的互操作性和协同性。战略设计原则必须把模型的重点放在捕获系统的概念核心,也就是系统的“远景”上。而且在完成这些目标的同时又不能为项目带来麻烦。为了帮助实现这些目标,需探索三个主题:上下文、精炼和大型结构。

        1、上下文是最不易引起注意的原则,但实际上它却是最根本的。无论大小,成功的模型必须在逻辑上一致,不能有互相矛盾或重叠的定义。有时,企业系统会集成各种不同来源的子系统,或包含诸多完全不同的应用程序,以至于无法从同一个角度来看待领域。要把这些不同部分中隐含的模型统一起来可能是要求过高了。通过为每个模型显式地定义一个Bounded Context,然后在必要的情况下定义它与其他上下文的关联,建模人员就可以避免模型变得缠杂不清。

        2、精炼可以减少混乱,并且把注意力集中到正确的地方。人们通常在领域的一些次要问题上花费太多的精力。整体领域模型需要突出系统中最有价值和最特殊的那些方面,而且在构造领域模型时应该尽可能把注意力集中在这些部分上。虽然一些支持组件也很关键,但绝不能把它们和领域核心一视同仁。把注意力集中到正确的地方不仅有助于把精力投入到关键部分上,而且还可以使系统不会偏离预期方向。战略精炼可以使大的模型保持清晰。有了更清晰的视图后,Core Domain的设计就会发挥更大的作用。

        3、大型结构是用来描述整个系统的。在非常复杂的模型中,人们可能会“只见树木,不见森林”。精炼确实有帮助,它使人们能够把注意力集中到核心元素上,并把其他元素表示为支持作用,但如果不贯彻某个主旨来应用一些系统级的设计元素和模式的话,关系仍可能非常混乱。有几种组织大型结构的方法,可以用它们作为基础结构,去构建我们需要的大型结构。如Responsibility Layer(职责层) 、Evolving Order等。

        这3种原则各有各的用处,但结合起来使用将发挥更大的力量。大型结构和精炼能够帮助我们理解各个部分之间的复杂关系,同时保持整体视图的清晰。Bounded Context(上下文)能够使我们在不同的部分中进行工作,而不会破坏模型或是无意间导致模型的分裂。把这些概念加进团队的Ubiquitous Language中,可以帮助开发人员找出大型模型的自己的解决方案。

二、保持模型的完整性

        模型最基本的要求是它应该操持一致,术语总是具有相同的意义,并且不包含互相矛盾的规则:虽然我们很少明确地考虑这些要求。模型内部的一致性又叫统一(Unification),这种情况下,每个术语都不会有模棱两可的意义,也不会有规则冲突。

        但大型系统开发并非如此理想。在整个企业系统中保持这种水平的统一是一件得不偿失的事情。在系统的各个不同部分中开发多个模型是很有必要的,但我们必须慎重地选择系统的哪些部分可以分开,以及它们之间是什么关系。我们需要是一些方法来保持模型关键部分的高度统一。这需要通过有意识的设计决策和建立特定过程才能实现。大型系统领域模型的完全统一即不可行,也不划算。

        有时人们会反对这一点,多个模型看上去似乎不够雅致。甚至对多个模型的抵触会导致“极富雄心”的尝试——将一个大型项目的所有软件统一到单一模型中。如果想这样做一定要考虑以下风险。

        (1)一次尝试对遗留系统做过多的替换。
        (2)大项目可能会陷入困难,因为协调的开销太大,超出了这些项目的能力范围。
        (3)具有特殊需要的应用程序可能不得不使用无法充分满足需要的模型,而只能将这些无法满足的行为入到其他地方。
        (4)另一方面,试图用一个模型来满足所有人的需求可能会导致模型中包含过于复杂的选择,因而很难使用。

        此外,除了技术的因素外,权力上的划分和管理级别的不同也可能要求把模型分开。而且不同模型的出现也可能是团队组织和开发过程导致的结果。因此,即使完全的集成没有来自技术方面的阻力,项目也可能面临多个模型。

        既然无维护一个涵盖整个企业的统一模型,那就不要再受到这种思路的限制。通过预先决定什么应该统一,并实际认识到什么不能统一,我们就能够创建一个清晰的、共同的视图。确定了这些之后,就可以开始着手开始工作,以保证那些需要统一的部分保持一致,不需要统一的部分不会引起混乱或破坏模型。

        我们需要用一种方式来标记出不同模型之间的边界和关系。我们需要有意识地选择一种策略,并一致地遵守它。

        为识别、沟通和选择模型边界及关系,我们使用了一些模式,Bounded Context(限界上下文)定义了每个模型的应用范围,而Context Map(上下文图)则给出了项目上下文以及它们之间关系的总体视图。这些降低模糊性的技术能够使项目更好地进行,但还不够。一旦确立了Context的边界之后,仍需要持续集成这种过程,它能够使模型保持统一。

        其后,在这个稳定的基础之上,我们就可以开始实施那些在界定和关联Context方面更有效的策略——从通过共享内核(Shared Kernel)来紧密上下文,到那些各行其道(Separate Ways)地进行松散耦合的模型。

        模型完整性模式的导航图 

1、模式:Bounded Context

        大型项目上会有多个模型共存,在很多情况下这没什么问题。不同的模式应用于不同的上下文中。但也会有引起含糊和混乱的情况。如:两个团队为同一个新系统开发不同的功能,那么他们使用的是同一个模型吗?他们的意图是至少共享其所做的一部分工作,但却没有界限告诉他们共享什么、没共享什么。而且他们也没有一个过程来维护共享模型,或快速检测模型是否有分歧。他们只是在系统行为不可预测时才意识到他们之间产生了分歧。

        即使在同一个团队中,也可能会出现多个模型。团队的沟通可能会不畅,导致对模型的理解产生难以捉摸的冲突。原先的代码往往反映的是早先的模型概念,而这些概念与当前模型有着微妙的差别。

        每个人都知道两个系统的数据格式是不同的,因此需要进行数据转换,但这只是问题的表面。问题的根本在于两个系统所使用的模型不同。当这种新差异不是来自外部系统,而是发生在同一个系统中时,它将更难发现。然而,所有大型团队项目都会发生这咱情况。

        任何大项目都会存在多个模型。而当基于不同模型的代码被组合到一起后,软件就会出现Bug、变得不可靠和难以理解。团队成员之间的沟通变得混乱。人们往往弄不清楚一个模型不应该在哪个上下文中使用。

        模型混乱的问题最终会在代码不能正常运行时暴露出来,但问题的根源却在于团队的组织方式和成员的交流方法。因此,为了澄清模型的上下文,我们既要注意项目,也要注意它的最终产品(代码、数据库模式等)。

        一个模型只在一个上下文中使用。这个上下文可以是代码的一个特定部分,也可以是某个特定团队的工作。如果模型是在一次头脑风暴会议中得到的,那么这个模型的上下文可能仅限于那次讨论。就拿本书来说,示例中所使用的模型的上下文就是那个示例所在的小节以及任何相关的后续讨论。模型上下文是为了保证该模型中的术语具有特定意义而必须要应用的一组条件。

        为了解决多个模型的问题,我们需要明确地定义模型的范围——模型的范围是软件系统中一个有界的部分,这部分只应用一个模型,并尽可能保持统一。团队组织必须一致遵守这个定义。

        因此:

        明确地定义模型所应用的上下文。根据团队的组织、软件系统的各个部分的用法以及物理表现(代码和数据库模式等)来设置模型的边界。在这些边界中严格保持模型的一致性,而不要受到边界之外问题的干扰和混淆。

        Bounded Context明确地限定了模型的应用范围,以便让团队成员对什么应该保持一致以及上下文之间如何关联有一个明确和共同的理解。在Context中,要保证模型在逻辑上统一,而不用考虑它是不是适用于边界之外的情况。在其他Context中,会使用其他模型,这些模型具有不同的术语、概念、规则和Ubiquitous Language的技术行话。通过划定明确的边界,可以使模型保持纯粹,因而在它所适用的Context中更有效。同时,也避免了将注意力切换到其他Context时引起的混淆。跨边界的集成必然需要进行一些转换,但我们可以清楚地分析这些转换。

        Bounded Context不是Module,有时这两个概念易引起混淆,但它们是具有不同动机的不同模式。确实,当两组对象组成两个不同模型时,人们几乎总是把它们放在不同的Module中。但人们也会在同一模型中用Module来组织元素,它们不一定要表达划分Context的意图。

识别Bounded Context中的不一致

        很多征兆都可能表明模型中出现了差异。最明显的是已编码的接口不匹配。对于更微妙的情况,一些意外行为也可能是一种信号。采用了自动测试的Continuous Integration可以帮助捕捉到这类问题。但语言上的混乱往往是一种早期的警告信号。

        将不同模型的元素组合到一起可能会引发两类问题:重复的概念和假同源。重复的概念是指两个模型元素(以及伴随的实现)实际上表示同一个概念。每当这个概念的信息发生变化时,都必须更新两个地方。每次由于新知识导致一个对象被修改时,必须重新分析和修改另一个对象。如果不进行实际的重新分析,结果就会出现同一概念的两个版本,它们遵守不同的规则,甚至有不同的数据。更严重的是,团队成员必须学习做同一件事情 的两种方法,以及保持这两种方法同步的各种方式。

        假同源可能稍微少见一点,但它潜在的危害更大。它要是指使用相同术语(或已实现的对象)的两个人认为他们是在谈论同一件事情,但实际上并不是这样。

        当发现这些问题时,团队必须要做出相应的决定。可能需要将模型重新整合为一体,并加强用来预防模型分裂的过程。分裂也有可能是由分组造成的,一些小组出于合理的原因,需要以一些不同的方式来开发模型,而且你可能也决定让他们独立开发。

三、参考文档

DOMAIN-DRIVERN DESIGN
TACKLING COMPLEXITY IN THE HEART OF SOFTWARE

领域驱动设计
软件核心复杂性应对之道

【美】Eric Evans 著   赵俐 盛海艳 刘霞 等 译

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch:如何创建搜索引擎

作者:Jessica Taylor 搜索引擎是生活中我们认为理所当然的事情之一。 每当我们寻找某些东西时,我们都会将一个单词或短语放入搜索引擎,就像魔术一样,它会为我们提供一个匹配结果列表。 现在可能感觉不那么神奇了,因为这…

【CSS】(标准流部分)易忘知识点汇总

一、元素 块元素 常见的块元素&#xff1a; <h1>~<h6>、<p>、<div>、<ul>、<ol>、<li>行内元素 常见的行内元素&#xff1a; <a>、<strong>、<b>、<em>、<i>、<del>、<s>、<ins&…

卷积神经网络CNN

图像基础知识 图像是由像素点组成的&#xff0c;每个像素点的取值范围为 : [0, 255] 。像素值越接近于 0 &#xff0c;颜色越暗&#xff0c;接近于黑色&#xff1b;像素值越接 近于255 &#xff0c;颜色越亮&#xff0c;接近于白色。 在深度学习中&#xff0c;我们使用的图像…

图神经网络实战——图论基础

图神经网络实战——图论基础 0. 前言1. 图属性1.1 有向图和无向图1.2 加权图和非加权图1.3 连通图和非连通图1.4 其它图类型 2. 图概念2.1 基本对象2.2 图的度量指标2.2 邻接矩阵表示法 3. 图算法3.1 广度优先搜索3.2 深度优先搜索 小结系列链接 0. 前言 图论 (Graph theory) …

@Transactional--开启事物后换源报错

一、问题出现的场景 系统架构设计、每个企业一个企业库、通过数据源切在平台库、和企业库之间动态切换完成业务操作。 二、跨库事物失效的原因 1、SpringTransactional不支持跨数据源事物&#xff0c;Spring 事物控制是基于数据库链接进行的&#xff0c;当数据源切换后&#x…

Python算法题集_单词搜索

Python算法题集_单词搜索 题22&#xff1a;单词搜索1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【原始矩阵状态回溯】2) 改进版一【字典检测原始矩阵状态回溯】3) 改进版二【矩阵状态回溯】 4. 最优算法5. 相关资源 本文为Python算法题集之一…

【Datawhale组队学习:Sora原理与技术实战】Attention

Attention Attention 注意力&#xff0c;从两个不同的主体开始。 论文&#xff1a;https://arxiv.org/pdf/1703.03906.pdf seq2seq代码仓&#xff1a;https://github.com/google/seq2seq 计算方法&#xff1a; 加性Attention&#xff0c;如&#xff08;Bahdanau attention&…

electron-release-server部署electron自动更新服务器记录

目录 一、前言 环境 二、步骤 1、下载上传electron-release-server到服务器 2、宝塔新建node项目网站 3、安装依赖 ①npm install ②安装并配置postgres数据库 ③修改项目配置文件 ④启动项目 ⑤修改postgres的认证方式 ⑥Cannot find where you keep your Bower p…

Sqli-labs靶场第12关详解[Sqli-labs-less-12]

Sqli-labs-Less-12 #手工注入 post传参了 根据题目看&#xff0c;像一个登录页面&#xff0c;尝试使用布尔型盲注测试能否登录网站 1. Username输入a a" 测试是否会有报错&#xff0c;burp抓包 报错&#xff1a;syntax to use near "a"") and passw…

【风格迁移】pix2pixHD:高分辨率图像生成

pix2pixHD&#xff1a;高分辨率图像生成 提出背景问题1: 如何提高生成图像的照片级真实感和分辨率&#xff1f;问题2: 如何利用实例级别的对象语义信息进一步提高图像质量&#xff1f;问题3: 如何实现图像合成的多模态性&#xff0c;允许交互式对象编辑&#xff1f; pix2pixHD …

Vue3中Vuex状态管理库学习笔记

1.什么是状态管理 在开发中&#xff0c;我们会的应用程序需要处理各种各样的数据&#xff0c;这些数据需要保存在我们应用程序的某个位置&#xff0c;对于这些数据的管理我们就称之为状态管理。 在之前我们如何管理自己的状态呢&#xff1f; 在Vue开发中&#xff0c;我们使用…

02、MongoDB -- MongoDB 的安全配置(创建用户、设置用户权限、启动安全控制、操作数据库命令演示、mongodb 的帮助系统介绍)

目录 MongoDB 的安全配置演示前准备&#xff1a;启动 mongodb 服务器 和 客户端 &#xff1a;1、启动单机模式的 mongodb 服务器2、启动 mongodb 的客户端 MongoDB 的安全配置启动演示用到的 mongodb 服务器 和 客户端启动单机模式的 mongodb 服务器&#xff1a;启动 mongodb 的…

光学遥感卫星分辨率的奥秘 !!

文章目录 前言 1、光学遥感卫星分辨率的多维视角 &#xff08;1&#xff09;空间分辨率 &#xff08;2&#xff09;光谱分辨率 &#xff08;3&#xff09;辐射分辨率 &#xff08;4&#xff09;时间分辨率 2、光学遥感分辨率的重要性 3、遥感分辨率的挑战与进步 4、未来展望 总…

《Spring Security 简易速速上手小册》第7章 REST API 与微服务安全(2024 最新版)

文章目录 7.1 保护 REST API7.1.1 基础知识详解7.1.2 重点案例&#xff1a;使用 JWT 进行身份验证和授权案例 Demo 7.1.3 拓展案例 1&#xff1a;API 密钥认证案例 Demo测试API密钥认证 7.1.4 拓展案例 2&#xff1a;使用 OAuth2 保护 API案例 Demo测试 OAuth2 保护的 API 7.2 …

【2024】利用python爬取csdn的博客用于迁移到hexo,hugo,wordpress...

前言 博主根据前两篇博客进行改进和升级 利用python爬取本站的所有博客链接-CSDN博客文章浏览阅读955次&#xff0c;点赞6次&#xff0c;收藏19次。定义一个json配置文件方便管理现在文件只有用户名称,后续可加配置读取用户名称&#xff0c;并且将其拼接成csdn个人博客链接ty…

OpenChat:性能高达105.7%,第一个超越ChatGPT的开源模型?

OpenChat&#xff1a;性能高达105.7%&#xff0c;第一个超越ChatGPT的开源模型&#xff1f; 前几天开源模型第一还是是Vicuna-33B、WizardLM&#xff0c;这不又换人了。对于开源模型的风起云涌&#xff0c;大家见怪不怪&#xff0c;不断更新的LLM榜单似乎也没那么吸引人了。 …

数学建模【因子分析】

一、因子分析简介 因子分析由斯皮尔曼在1904年首次提出&#xff0c;其在某种程度上可以被看成是主成分分析的推广和扩展。 因子分析法通过研究变量间的相关系数矩阵&#xff0c;把这些变量间错综复杂的关系归结成少数几个综合因子&#xff0c;由于归结出的因子个数少于原始变…

C/C++工程师面试题(数据库篇)

索引的优缺点 索引是一种支持快速查找特定行的数据结构&#xff0c;如果没有索引&#xff0c;就需要遍历整个表进行查找。用于提高数据检索的速度和效率。 好处&#xff1a; 提高检索速度&#xff1a; 索引可以加快数据的检索速度&#xff0c;因为它们允许数据库系统直接定位到…

Mysql学习之MVCC解决读写问题

多版本并发控制 什么是MVCC MVCC &#xff08;Multiversion Concurrency Control&#xff09;多版本并发控制。顾名思义&#xff0c;MVCC是通过数据行的多个版本管理来实现数据库的并发控制。这项技术使得在InnoDB的事务隔离级别下执行一致性读操作有了保证。换言之&#xff0…

【Tomcat】The CATALINA_HOME environment variable is not defined correctly

文章目录 一、问题二、解决办法三、优化 一、问题 运行绿色版Tomcat时&#xff0c;单击apache-tomcat-9.0.27\bin\startup.bat时窗口一闪而过。 检查JAVA_HOME环境变量&#xff0c;可以发现并没有问题。 为了检查错误&#xff0c;将startup.bat程序使用文本编辑器打开&#x…