当SOA遇到DDD

简介: 【8月更文挑战第15天】

本文讨论软件设计中的决策,特别是关于将较大的系统拆分为多个可独立部署的服务端点。不会特别讨论【服务端点设计】,但我想探讨一下为创建多个服务应用程序进行构思的阶段。

面对复杂问题,通常试图理解复杂性的各部分。将问题拆解为更易于理解和处理的小模块,可以更有效地应对。

如同在许多产品/项目管理周期中描述的,对现实生活问题,通常直觉驱动。我们并没有使用某种公式理解前往需要签证的国家所需步骤。我们逐步了解到需要签证才能旅行,慢慢掌握需要哪些文件、哪些表格需要填写及咋填表。当我们处理其中的一步,不会在脑海中保留整个过程的所有细节,而是专注当前任务。这与任务完成规模有关。真正标准是时间或进度安排、执行任务的精力、认知能力及它与任务熟悉度的关系,甚至包括执行这些任务的物理地点(如领事馆与照相馆等)。

软件开发亦是如此。虽然多年“瀑布式”开发流已广泛应用,但最终主要还是基于启发式和经验的估算技术(如规划扑克、T恤尺寸估算)及敏捷过程占据主导。正如在现实,我们尝试不过分细化规划整个过程,而是根据最新的进展来把握整体方向。

同样理念也适用于根据问题建模的软件。开始将它们拆分为不同应用程序,目的是更容易管理单个应用程序,更快开发和部署,并减少依赖关系,最后还带来更多技术选择的自由。没有一套完整流程适用于所有情况。我们会查看各部分,并认识到我们在设计模式或技术方面的集体经验,努力选择最佳方案并应用。

一种用于理解和解决软件设计复杂性的技术是领域驱动设计(DDD)。DDD提倡基于业务现实建模,并与我们的用例相关。随其热度下降,很多人可能忘记DDD方法实际上在理解当前问题并设计软件以达成对解决方案的共同理解方面非常有帮助。构建应用程序时,DDD将问题描述为领域和子领域。

它会将独立的步骤或问题领域定义为限界上下文。强调使用通用语言讨论问题,并引入许多技术概念,如[实体、值对象和聚合根规则]来具体实现。有时这些技术规则被视为实现DDD的硬性障碍,但最终,人们往往忘记最重要的是将代码工件与业务问题保持一致,并使用相同的通用语言。

设计为服务应用程序的限界上下文

我想讨论的架构风格与微服务相似。它涉及将单体应用程序拆分为多个独立的服务应用程序,或从一开始就借助限界上下文这一DDD的概念来单独开发它们。

有许多资源突出更细粒度服务的优点,作为微服务叙述的一部分。越来越多博客讨论在向细粒度服务过渡前或过渡期间你应该具备的防护网和可能遇到的陷阱。我将尝试不重复微服务的好处或为迁移到这种架构而需要的支持元素,而是重点讨论如何通过应用领域驱动设计的概念来更好地分离这些服务。

实例

一个借记/信用卡收单领域。这个领域可以(如很多情况下的那样,不幸地)被实现为一组单体应用程序。之所以有多个应用程序,仅因在不同应用程序中存在一些硬性技术限制(如希望执行批处理过程)。

大多数成功的架构都认识到通过DB集成是一种不好做法,因为它模糊了技术应用程序和业务职责之间的边界,使业务逻辑泄露到DB,并通过增加应用程序服务器数量来阻碍水平扩展。因此,向更好架构的演进表现为单体应用程序的服务集成。

现在,应用程序之间的边界变得更清晰了。但正如你所见,仍然存在隐藏的DB交互,这次是在各独立应用程序内部发生。我称它们为隐藏的,因为它们通常一开始很难被注意到。随时间推移,代码缠绕会使原本分离的业务流程在人为上联系,并在业务开发引入更多摩擦,因为这种共存需要共同部署独立的功能,可能减缓开发进度。

若你有一个领域模型指导你,领域建模有助识别和分离纠缠在一起的实现。若你还没现有应用程序的领域模型(这在大多数情况下是真实的),与其通过代码来理解不同职责,不如建立一个领域模型并将其映射到手头的应用程序,可能是更好方法。这不仅节省时间,还可避免陷入细节困境。而且,若业务团队与开发团队存在差距(可能是领域模型一开始就不存在的主要原因),讨论领域模型并将其与现有应用程序的功能对应起来,有助于弥补这一差距。

设计演进的下一步是将领域边界分离反映到我们的架构及限界上下文中。一个领域有多个限界上下文,意味着同一领域内可能有多个服务应用程序。

通过合适的领域模型,潜在的拆分点更加清晰,使我们能从更细粒度的应用程序中受益,如独立发布和版本控制、纯粹的基于能力的服务端点等,大多数这些优点已经在微服务文章中讨论过了。虽然许多关于微服务的讨论集中在技术中立性和开发纪律(避免/打破单体)上,但对于我们大多数人所处理的应用程序而言,领域和设计层面的考虑同样具有很高的价值。在转向微服务架构(借助领域模型)之后,DDD和更细粒度的服务可以相互协作,共同支撑。

这也将为团队提供一定程度的独立性,更精细的服务能力和更解耦的交互,如许多微服务文章中所解释的那样。

此外,正如案例信用卡支付收单领域中所见,这不是我们服务可达到的最细粒度分离。相反,这是通过我们的领域知识指导下的最有意义的分离。关键不在于服务的规模,而在于业务能力的划分。我认为这就是许多人所说的“正确的SOA”。
关注我,紧跟本系列专栏文章,咱们下篇再续!

作者简介:魔都架构师,多家大厂后端一线研发经验,在分布式系统设计、数据平台架构和AI应用开发等领域都有丰富实践经验。

各大技术社区头部专家博主。具有丰富的引领团队经验,深厚业务架构和解决方案的积累。

负责:

  • 中央/分销预订系统性能优化
  • 活动&券等营销中台建设
  • 交易平台及数据中台等架构和开发设计
  • 车联网核心平台-物联网连接平台、大数据平台架构设计及优化
  • LLM Agent应用开发
  • 区块链应用开发
  • 大数据开发挖掘经验
  • 推荐系统项目

    目前主攻市级软件项目设计、构建服务全社会的应用系统。

参考:

目录
相关文章
|
测试技术 领域建模 定位技术
基于事件风暴的需求分析 | 方法案例一
事件风暴(Event Storming)源自领域驱动设计社区,由 Alberto Brandolini 在2012 年发明[1]。 事件风暴最早的名字是基于事件的建模(Event-Based Modeling),正如这个名字所暗示的,事件风暴在发明之初的核心目的是领域建模,在今天的大多数文献和实践中,事件风暴的核心关注点都是领域模型和软件架构。
5304 2
基于事件风暴的需求分析 | 方法案例一
|
设计模式 供应链
阿里高级技术专家方法论:如何写复杂业务代码?
面对零售通如此复杂的业务场景,如何在架构和代码层面进行应对,是一个新课题。
19966 2
|
uml
状态机
首先需要考虑涉及到哪些状态节点和哪些事件,如何方便状态节点的获取、状态节点如何串联起来呢?串联的方式下,如何拿到下一个状态节点?如果基于角色,如何实现? 我们知道工作流可以实现基于角色进行流程的流转,但是此时我们涉及到事件和状态,会出现多个分支,如果使用工作流实现,流程处理上,比如activiti上,可能比较复杂,因此考虑比较轻量级的状态机来实现的话,相对来说要方便一些。
2029 0
状态机
|
Java 数据库连接 定位技术
|
SQL 运维 安全
闲鱼交易实时资损防控体系
聊一聊资损防控体系和闲鱼实践
7501 0
闲鱼交易实时资损防控体系
|
微服务 测试技术 Java
阿里技术专家详解 DDD 系列- Domain Primitive
关于DDD的一系列文章,希望能继续在总结前人的基础上发扬光大DDD的思想,但是通过一套我认为合理的代码结构、框架和约束,来降低DDD的实践门槛,提升代码质量、可测试性、安全性、健壮性。
63468 17
阿里技术专家详解 DDD 系列- Domain Primitive
|
存储 算法 安全
国密算法及简单使用
国密算法,即国家密码局认定的国产密码算法,主要用于保护国家关键信息基础设施和商业领域的加密通信和数据安全。根据 2019年10月26日第十三届全国人民代表大会常务委员会第十四次会议通过的《中华人民共和国密码法》,国家对密码实行分类管理,密码分为核心密码、普通密码和商用密码
2797 4
|
SQL 缓存 NoSQL
接口的幂等性设计和防重保证,详细分析幂等性的几种实现方法
本篇文章详细说明了幂等性,解释了什么是幂等性,幂等性的使用场景,讨论了幂等和防重的概念。分析了幂等性的情况以及如何设计幂等性服务。阐述了幂等性实现防重的几种策略,包括乐关锁,防重表,分布式锁,token令牌以及支付缓冲区。
9928 0
接口的幂等性设计和防重保证,详细分析幂等性的几种实现方法
|
11月前
|
人工智能 自然语言处理 搜索推荐
2025金融行业Agent案例全场景盘点:银行证券保险实战案例+落地解析(含实在Agent标杆实践)
本文系统梳理银行、证券、保险三大领域金融Agent标杆案例,整合实在智能等头部厂商实战经验,覆盖应用场景、技术路径与落地成效,全面解析从运营提效到智能决策的完整解决方案,助力金融机构实现可落地的智能化升级。
4173 156
|
关系型数据库 MySQL 索引
MySQL in 太多的解决方案
MySQL in 太多的解决方案
1808 0

热门文章

最新文章