热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

DDD子域与有界上下文的关系

假设有一个农业机械零件的批发商。他们建立了一个B2B网上商店,供经销商和机器维修公司订购。在他们无处不在的统一语言与术语中,订单代表了这个自动化流程:它使客户能够挑选产品,应用正确



假设有一个农业机械零件的批发商。他们建立了一个 B2B 网上商店,供经销商和机器维修公司订购。在他们无处不在的统一语言与术语中,订单代表了这个自动化流程:它使客户能够挑选产品,应用正确的折扣,并将其推送到 送货。
如果这个批发商与竞争对手合并:他们是老牌企业,拥有稳固的客户群和庞大的目录。后者也有一个订购系统,但它更传统:客户打电话,客户经理输入订单,应用任意折扣,然后将其推送到送货。
合并后的公司仍然只有一个 Sales销售 子域,但它现在有两个 Sales Bounded Contexts销售上下文。它们两个模型中都有像 Order 和 Discount 这样的概念,这些概念的含义基本相同。两个批发商的员工就订单或折扣达成一致。但是他们有不同的使用流程,他们在表单中输入不同的信息,并且有不同的业务规则。
在技​​术意义上,差异体现在对象设计、方法、工作流、应用折扣的逻辑、数据库表示和一些统一语言与术语中。不过,它运行得更深入:对于软件设计人员来说,要在任一有界上下文中都富有成效,他们必须了解这两种模型之间的许多区别:有界上下文代表可理解边界。( 上下文为王 )
在一个完美设计的系统中,我们理想的有界上下文通常会与子域的边界很好地对齐。但有界上下文实际上是遵循系统演进的。
系统随着公司组织发展。不幸的是,这个发展过程中呈现的新概念经常不以符合我们设计的方式出现,我们对变得更加不一致的代码感到不舒服了,只要我们有时间就想要统一这些新旧概念并制作干净的抽象,因为我们应该创建一个设计良好的系统。
 

子域与有界上下文区别
上面的例子简单地表明,单个子域实际可以由多个有界上下文表示。
领域与有界上下文区别:有界上下文可能与应用或服务边界一致,也可能不一致。同样,它们可能与领域边界对齐,也可能不对齐。领域存在于问题空间中。领域是组织如何看待其活动和专业领域的方式;而有界上下文是属于解决方案空间的一部分,它们是经过深思熟虑的设计选择。
作为系统设计师,您选择这些边界来管理系统的可理解性,通过使用不同的模型来解决领域的不同方面。
对于上面案例,系统设计者可以:


  • 合并两个销售上下文,
  • 将一个迁移到另一个里面,
  • 建立一个新的销售上下文来取代两者,
  • 推迟这项努力,
  • 或者不做任何事情并保留现有的两个上下文。

这些都是设计选择,即使 CEO 最终会从这些选项中进行选择(例如,由于预期的投资回报率)。或许,在权衡之后,将两个销售上下文并排放置是目前最好的战略设计选择,因为它允许合并后的公司专注于新的机会。毕竟,现有系统确实服务于它们的目的。这里的要点是,为单个子域设置两个有界上下文可能是一个非常有效的选择。
 

一个子域有多个上下文
当没有外部触发(如批发商合并)时,您是否还会故意选择将单个域拆分到多个上下文中?
假设你为一位小商品贸易商提供咨询。他们专注于一些特殊商品,由 20 名交易员、一些运营支持角色和大约 10 名开发人员组成。首席工程师参观了该系统,该系统由单个交易域的 20 个有界上下文组成。每个交易者都有一个上下文。
这看起来很奇怪,我们的本能是找出相似之处,将它们抽象出来,并使它们可重复使用。开发人员没有这样做。他们充其量只是复制粘贴彼此的代码块。首席工程师主要关心的是“我们是否针对我们的情况进行了优化设计?” 他们担心自己陷入了大麻烦。
每个交易者都有自己的交易代表。整个公司甚至有多种金钱货币体系。交易者的算法不同,尽管许多人做的事情有些相似。每个交易者都有不同的仪表板。开发人员使用相同的第三方库,但是当他们彼此共享自己的代码时,他们并没有尝试统一它。相反,他们复制了代码,并随着时间的推移按照他们认为合适的方式进行修改。许多工作涉及数学算法,而不是典型的面向业务的 IT。
事实证明,每个交易者都有独特的需求。他们需要快速行动:他们尝试了不同的算法、预测和看待市场的方式。开发人员为交易者服务,并与他们密切合作,不断将他们的想法转化为新代码。交易员受到高度重视,他们是压力大、竞争激烈的环境中的首要人物。如果你想成为其中的一部分,你就不能成为一个缓慢的编码者或一个数学懒鬼。没有(Jira)票,没有功能积压。这是领域专家和程序员之间的终极快速反馈循环。
事情每天都在快速变化。找到正确的抽象需要大量的协调,它会大大减慢开发速度。试图统一代码会毁了公司。
这种设计并不充满技术债务。这也不是遗留问题,多年来设计意外地以这种方式发展。该代码正在工作。这种缺乏统一抽象的设计是一种深思熟虑的设计选择,符合目的,即使起初看起来是一个激进的选择。所有的开发者和交易者都对它感到满意。
这些也不仅仅是具有大量重复代码的独立程序。这是一个单一的领域,分为 20 个有界上下文,每个有自己的领域模型、自己的通用语言和自己的变化率。协调模型中的语言和概念会增加这种高速环境中的摩擦。通过故意选择设计单独的上下文,他们消除了这种摩擦。
 

权衡
权衡设计选择的后果是:当开发人员需要帮助解决问题时,他们必须让其他开发人员跟上进度。每个开发人员在另一个有界上下文中工作时,都希望他们必须进行上下文切换。毕竟,它们的术语和概念彼此不同,即使它们共享相似的术语。上下文切换是有代价的,如果您整天处理不同的项目,您可能已经体验到了这种代价。但是在这里,因为上下文显然是有界的,所以这并没有引起很多问题。有时,通过向具有相似上下文背景(但有界上下文不同)的另一位开发人员解释问题,解决方案变得显而易见。
  

一般 IT 系统中的多个有界上下文
交易系统是一个极端的例子,您不会遇到许多环境,其中具有 20 个有界上下文的单个子域是有意义的。但是在许多常见情况下,您应该考虑拆分域。如果在您的公司中,个人客户和企业客户的定价规则不同,那么在单个域模型中统一这些规则的努力可能会花费更多。或者在薪资系统中,受薪员工和计时员工的规则和流程不同,您最好拆分此域。
  

总结
正确的上下文边界遵循业务的轮廓。不同的区域在不同的时间以不同的速度变化。随着时间的推移,看起来相似的东西可能会以令人惊讶和出人意料的方式产生分歧(如果有机会的话)。将概念压缩到单个模型中是有限制的。通过使其服务于两种不同的业务需求并持续承担协调成本,您正在使模型复杂化。这是一种隐藏的依赖债务。
我们可以在这里推导出两种启发式方法:

  1. 限界上下文/有界上下文不应该服务于设计师的感性和对完美的需求,而应该提供商业机会。
  2. 变化率启发式:考虑组织有界上下文,以便它们管理以相同速度变化的相关概念。

由 Mathias Verraes @mathiasverraes和 Rebecca Wirfs-Brock @rebeccawb 撰写。

 


推荐阅读
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
  • 程序员如何优雅应对35岁职业转型?这里有深度解析
    本文探讨了程序员在职业生涯中如何通过不断学习和技能提升,优雅地应对35岁左右的职业转型挑战。我们将深入分析当前热门技术趋势,并提供实用的学习路径。 ... [详细]
  • 本文总结了优化代码可读性的核心原则与技巧,通过合理的变量命名、函数和对象的结构化组织,以及遵循一致性等方法,帮助开发者编写更易读、维护性更高的代码。 ... [详细]
  • 在 Ubuntu 22.04 LTS 上部署 Jira 敏捷项目管理工具
    Jira 敏捷项目管理工具专为软件开发团队设计,旨在以高效、有序的方式管理项目、问题和任务。该工具提供了灵活且可定制的工作流程,能够根据项目需求进行调整。本文将详细介绍如何在 Ubuntu 22.04 LTS 上安装和配置 Jira。 ... [详细]
  • 鼠标悬停出现提示信息怎么做
    概述–提示:指启示,提起注意或给予提醒和解释。在excel中会经常用到给某个格子增加提醒信息,比如金额提示输入数值或最大长度值等等。设置方式也有多种,简单的,仅为单元格插入批注就可 ... [详细]
  • 1.执行sqlsever存储过程,消息:SQLServer阻止了对组件“AdHocDistributedQueries”的STATEMENT“OpenRowsetOpenDatas ... [详细]
  • 深入理解ExtJS:从入门到精通
    本文详细介绍了ExtJS的功能及其在大型企业前端开发中的应用。通过实例和详细的文件结构解析,帮助初学者快速掌握ExtJS的核心概念,并提供实用技巧和最佳实践。 ... [详细]
  • 由二叉树到贪心算法
    二叉树很重要树是数据结构中的重中之重,尤其以各类二叉树为学习的难点。单就面试而言,在 ... [详细]
  • 本文详细介绍了如何解决 Microsoft SQL Server 中用户 'sa' 登录失败的问题。错误代码为 18470,提示该帐户已被禁用。我们将通过 Windows 身份验证方式登录,并启用 'sa' 帐户以恢复其访问权限。 ... [详细]
  • 本文详细介绍如何使用 Apache Spark 执行基本任务,包括启动 Spark Shell、运行示例程序以及编写简单的 WordCount 程序。同时提供了参数配置的注意事项和优化建议。 ... [详细]
  • 深入剖析JVM垃圾回收机制
    本文详细探讨了Java虚拟机(JVM)中的垃圾回收机制,包括其意义、对象判定方法、引用类型、常见垃圾收集算法以及各种垃圾收集器的特点和工作原理。通过理解这些内容,开发人员可以更好地优化内存管理和程序性能。 ... [详细]
  • 智能投顾机器人:创业者如何应对新挑战?
    随着智能投顾技术在二级市场的兴起,针对一级市场的智能投顾也逐渐崭露头角。近日,一款名为阿尔妮塔的人工智能创投机器人正式发布,它将如何改变投资人的工作方式和创业者的融资策略? ... [详细]
  • Jira 是由澳大利亚 Atlassian 公司开发的一款高效的问题追踪与项目管理工具,广泛应用于软件测试领域。它不仅能够对各类问题进行精准跟踪,如缺陷管理和任务分配,还能通过灵活的工作流定制和丰富的插件生态系统,显著提升团队协作效率和项目透明度。Jira 在软件测试中的应用,不仅有助于提高测试效率,还能确保产品质量,是现代软件开发团队不可或缺的工具之一。 ... [详细]
  • 寻求帮助:构建开发人员特征标签系统 ... [详细]
  • 本文整理了Java中com.atlassian.jira.issue.Issue.getDueDate()方法的一些代码示例,展示了Issue.getDue ... [详细]
author-avatar
蜃海
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有