前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >互联网那些事儿 | 从领域驱动设计(Domain-Driven Design)到工程实践

互联网那些事儿 | 从领域驱动设计(Domain-Driven Design)到工程实践

原创
作者头像
Java研究者
修改2023-12-11 19:06:56
6921
修改2023-12-11 19:06:56
举报

把时间拨回到 90年代,关系型数据库系统如Oracle、IBM DB2和Microsoft SQL Server等逐渐成为企业和互联网应用的主流选择;在软件架构设计上,随着关系数据库的迅速发展,以数据层作为基座的三层模型(数据访问层、业务逻辑层、表现层)逐渐兴起成为了主流架构设计。回想当时的三层模型架构,颇有一番类似如今到处都在谈论微服务架构、领域驱动架构的味道。

随着企业系统信息化进一步的发展,软件复杂程度进一步上升,基于三层模型架构的研发变得越来越复杂。首先,三层模型架构出发的角度更多的从技术上的设计,对于大型信息化复杂系统的可理解性与维护性存在的天然的不足;其次,由于业务需求复杂性与数量的指数上升,技术人员与业务人员对系统的理解存在较大差异,从而影响了需求设计到软件实现的效率。90年代末期的时候,开始越来越多的相关人员对 现有架构设计进行了反思,这也就是 领域驱动设计Domain-Driven Design)出现与兴起的大背景。

到了 2003年,Eric Evans 出版了《领域驱动设计》一书,这本书常被认为是 领域驱动设计(Domain-Driven Design)概念的主要来源之一。随后 领域驱动设计 在软件研发领域开始持续发展并受到广泛关注,越来越多的人分享了更多的实践经验、案例和技术观点。领域驱动设计的三个英文单词都是以D开头,也常被简称为DDD。从这些发展演化可以看到,领域驱动设计(Domain-Driven Design) 的提出是致力于解决传统软件开发方法在复杂业务领域下,理解、建模和实现的困难,通过强调业务领域的核心地位,提高软件系统对业务需求的表达。

PS:本文目标不是着重讨论 领域驱动设计(Domain-Driven Design)中各种专业术语,而是以实际架构设计案例为基础进行解读。在文末会提供代码工程示例。

业务领域的初步划分

在供应链相关系统中,WMS(Warehouse Management System)是典型的复杂业务场景系统。仓内作业涉及众多流程,包括计划入库、销退入库、货品上架、库存盘点、波次作业、订单拣选、打包出库等。这些操作在不同仓库可能有不同要求,如正/残品不能存放同一库区、相同批次商品不能存放同一库位、订单出库优先从拣选库区进行等。再考虑到行业层面,例如跨境仓库需清关流程,猫超零售仓库需订单时效管理,高价值商品如iPhone需要SN码管理等。这些仅是随意举例一些场景业务,足可见其需求的多样性与复杂性。

所以对 WMS系统进行架构的时候, 采用领域驱动设计(Domain-Driven Design)会是个不错的选择,充分结合业务领域进行架构设计来保障系统的可理解性、可维护性。

不同仓库涉及的行业也十分多样,包括跨境电商、零售电商、化工产品、汽车构件、服装饰品等。以业务行业为领域划分并非明智之举,因为业务行业的广泛多样性不适合作为划分领域的标准。总结下经验的话,领域(Domain)划分并不能随意选取某一业务维度作为领域划分的依据。

回到 WMS 系统本身而言功能聚焦在仓库的作业,如果把仓库具体各种操作罗列出来,并结合工作经验以及FLUX-WMS、CAINIAO-WMS、SAP-WMS等产品功能设计,站在巨人的肩上进行抽象分析,最终也可以将作业水平切分为:入库操作、库内操作、库存操作、出库操作、基础资料维护(库区、库位、商品等信息维护)。业务行业各种需求,将其设计成叠加在这些仓库作业之上的规则与特殊流程要求。

总体说来,以仓内作业为基础进行水平领域切分,以业务行业进行垂直业务切分作为组件与流程。将 WMS初步划分为:入库领域、库内领域、库存领域、出库领域、基础领域。总结下经验的话,领域(Domain)划分可以从共性业务的角度进行抽象,同时要具备有限性。

领域内的架构设计

边界分析

在进行领域内架构设计时,边界交互和接口服务是关键考虑因素之一。举例入库流程来说WMS入库操作流程往往都会支持 RF移动设备端的操作 以及 PC端的操作,因此边界交互上需要支持这些终端产品的接口服务。这些接口服务可能采用多种协议,比如REST、RPC类或Socket协议等,以适配和满足不同终端产品的操作需求。

除了支持对终端产品的操作,WMS通常需要与外部系统如ERP、TMS(运输管理系统)等进行交互。举例来说,可能需要通过ERP下发入库通知单,或者在包裹出库后通知TMS以启动后续的运输流程。实现这些交互,WMS需要提供Open API或Message类服务接口的支持。

WMS单个领域自身而言,与其他领域之间的交互也是至关重要的。举例来说,执行入库操作时可能需要查询基础域货品信息或货主信息,而完成入库后又需要对库存域的库存进行调整等。这里简单勾画下概要架构设计图。

领域内分层

在之前讨论的领域划分中已经提及,各个业务行业的流程需求非常丰富且多样化。鉴于这样的业务背景,水平切分的领域内需要具备支持业务流程灵活编排的能力。这里把业务流程灵活编排的基本单位定义为组件,当然也不希望重复的编写相似的组件,因此组件的设计要支持可扩展。

领域驱动设计中,领域内常采用 Interfaces、Core 和 Infrastructure 的分层架构。

  • Interfaces层: 聚焦于实现对外部各种场景服务的接口协议,并进行数据适配;
  • Core层:承载领域核心业务逻辑的实现,这里考虑到主要业务逻辑在于组件与流程编排,因此组件的实现架构置于这一层;
  • Infrastructure层:承载技术性的基础设施支撑,包括数据库对象的CURD操作和具体领域内的持久化存储对象等。

细化功能分析

完成架构分层后,进一步扩展考虑更多细节;比如 错误码设计、单个域内状态设计、业务对象(BO)建模、组件研发约定、公共对象建模、权限鉴定等等。每一个点都可以结合自身领域承担的业务进行设计,当然细节功能往往非常多也可以按照敏捷的方式进行,小步迭代来完成设计与实现。

受限于篇幅这里就不一一详细展开。在此仅在概要架构设计图上简单的罗列一些点。

工程结构设计

在完成一定的细化架构分析设计后,开始将架构设计转换为工程结构。举例以 Java工程为例,领域的层次架构用包(Package)的形式来表达。

尽管一直强调 领域驱动设计(Domain-Driven Design)的架构设计与业务结合;但细化完架构后,结合细化后的技术特点,可以进行一些领域划分上的调整。

例如,从横向角度审视WMS的各个业务领域,在每个领域的Infrastructure层都可能存在大量可共用的部分;因此,考虑单独划分出一个特殊的公共领域(Common Domain),该领域仅只有Infrastructure层,用于支撑WMS各个业务领域共享的基础设施部分。

在业务细化的过程中,也可以看到系统需要支持用户管理、权限管理等系统管理功能。架构上可以考虑将这些相关模型单独划分到一个新领域来支持,即系统管理领域(System Domain)。

总结下经验的话:领域(Domain)划分强调业务领域的核心地位,但并非仅限于业务领域

领域间的架构设计

领域间的架构设计重点之一是设计领域间的接口服务。设计需要考虑多种因素,如业务场景、预期调用量、团队研发人员的技术能力、模块复用性、研发时间要求等等。需要在综合考虑这些因素的基础上进行设计,以确保系统在不同领域间能够有效地通信和交互。

提及一点容易被忽略的地方,约定下 POJO 的使用很重要,以防止模型泛滥,这里仅给个参考。

  • PO(Persistent Object):将单个领域视作一个整体,应当避免多次对象转换的内耗,因此在单个领域内部函数实现中都可以直接使用。
  • BO(Business Object): 核承载业务模型的核心部分,作为Core层的模型存在,支持Core和Interface两层的内部需求使用。
  • DTO(Data Transfer Object):专门用于Interface层对外服务的返回对象。
  • VO(View Object):专门用于Interface层Web服务对外返回的对象。

回头再看 领域驱动设计

笔落到此处,不妨回过头再看看 领域驱动设计(Domain-Driven Design)。在产品接收到新的业务行业需求时,将这些需求具体拆分到每个领域的流程和功能改造点。研发团队会根据业务领域理解这些功能的实现,并提供相应的技术方案。即便是业务人员,通过一些架构设计图也能大致感受到系统的设计。可见,领域驱动设计的架构设计在一定程度上解决了复杂业务领域所带来的系统理解和维护难题,提升了产品、业务、研发和测试工作的效率。

建议当研发工程师和产品设计师,因为某个需求不明确、复杂代码难以理解修改 而近乎可能打起来的时候,或许此时应当一起把 “锅” 扔给架构师。作为一个好的架构师,一定程度上可以解决这些 看似偶然实则必然 的问题。

行文最后附上参考工程:https://github.com/quincik/ElephantWMS

欢迎关注笔者腾讯专栏、博客等,期待点赞、收藏。

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 业务领域的初步划分
  • 领域内的架构设计
    • 边界分析
      • 领域内分层
        • 细化功能分析
          • 工程结构设计
          • 领域间的架构设计
          • 回头再看 领域驱动设计
          相关产品与服务
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
          http://www.vxiaotou.com