ITPub博客

首页 > 数据库 > Oracle > DDD 在京东 DevOps 项目协作领域的落地实战

DDD 在京东 DevOps 项目协作领域的落地实战

原创 Oracle 作者:京东云技术新知 时间:2020-09-18 17:39:16 0 删除 编辑

DDD 即领域驱动设计(Domain-Driven Design) 。它 来源于著名建模专家 Eric Evans 发表的非常具有影响力的书籍:《domain-driven design –tackling complexity in the heart of software》(中文:领域驱动设计—软件核心复杂性应对之道)。 其最早广泛应用于传统软件架构设计中。


今年4月,InfoQ 发布了软件架构与设计的趋势报告。在报告中可以看出, 微服务、领域驱动设计等已成为目前软件开发行业的主流趋势 ,笔者也了解到, DDD 已成为大部分企业微服务落地、中台建设的指导思想


(图片来源:infoQ)


隔离变化和沉淀复用




在互联网时代,业务系统构建初期,场景通常简单清晰,基于数据库表设计+CRUD 就能支撑业务的敏捷迭代。 随着时间的推移,场景和业务逻辑变得复杂、定制,模块之间彼此耦合,系统变得越来越臃肿,往往牵一发而动全身 。即使加一个字段这样看似简单的逻辑,光梳理对其他功能点和模块的影响,就至少需要一个对业务和代码都很熟悉的团队老成员才能稳妥敲定。相信一个实现1年以上的业务系统,其架构和代码就有可能正在经历着以上这些,开始慢慢腐化。


一个最经典的例子——电商系统里面诸如以下 product 类的设计(现实中字段数可能几百个),它是不符合高内聚低耦合这个架构设计原则的:


  • product 类包罗万象,什么领域的知识都知道;其职责不清晰,在 沉淀 复用 上,团队成员的期望都不一致,实现姿势可能千奇百怪;

  • 采购、仓储、配送业务领域的逻辑变动可能都要修改 product ,一个高内聚的系统设计,是需要尽可能 隔离变化 ,使之产生的影响最小且控制在一定边界内。


DDD 通过划分限界上下文,拆分子领域,实现解耦和复用:


以下图片来自软件开发教父:M artin Fowler。诚然,为应付越来越复杂的业务逻辑, 以自顶向下设计的领域聚合模型替代数据表模型,才能真正实现以业务实体为核心的灵活拓展

  • 面向过程的脚本,不能很好地被扩展;

  • 面向数据表的设计,过度关注数据忽略行为, 不能很好地被复用。


以上,让经历互联网泡沫存活下来的系统弄潮儿逐渐重燃对 DDD 的热情,希望借助 DDD 能重拾建造更合理软件架构的信心。但在落地上,荆棘环生,困境各异。下面我们来介绍一下 DDD 在京东 DevOps 项目协作领域的落地实践。


将 DDD 应用到组件化




在京东内部,项目协作领域有两个用户群体覆盖特别广(总用户数 8W+)的系统:PMP 和行云。


PMP 是一个更面向项目经理的项目管理软件,包含项目流程管理、需求管理、里程碑管理、任务管理、工时管理、成本管理、OKR 管理、ROI 验证和满意度评分等。 在架构设计上,PMP 是一个非常庞大的单体应用,其前后端不分离,所有业务逻辑糅杂在一起,项目表单字段数达到了 100+ 。经过时间和组织的变迁,在可扩展性和可维护性上,简直是场灾难。


行云 起初的定位是面向研发的敏捷协同软件,包含跨部门需求管理、敏捷迭代和任务管理等。随着行云的广泛使用,将 PMP 功能融合到行云的呼声越来越高。


同时, 行云对公司外部提供 T oB 服务。 内外部存在着大量差异化的场景和业务,单纯靠以往的不断添加 if else 揉泥球的方式,已经完全行不通。新的定位和背景下,要求我们必须将业务逻辑拆分为一个个灵活的组件,做到复用与逻辑沉淀;另一方面,差异化的逻辑可以灵活扩展 。这其中有着巨大的挑战:



上图中间圆弧描述的是我们在对组件拆分时参考的原则(业务可独立运营、高内聚低耦合、数据完整性、渐进性),以此为基础,在应对业务和技术视角上的挑战时,我们采取的相关 DDD 战略。


业务的挑战




PMP 和行云中都有需求管理、任务管理。这其中需求、任务是不是一个概念?项目、需求、迭代、任务等之间是什么关系? 如何对内和对外沉淀一套清晰可复用的业务组件?


DDD 中概念比较多,包含限界上下文、聚合、聚合根、实体、值对象等,本文先不关注这些细节,直接 聚焦以下问题:


1、 划分边界,识别领域对象或者领域类,保证其职责清晰纯粹;

2、 明确领域类之间的关联、依赖,界定调用关系和方式。


通过领域分析建模,形成统一语言,最终 将项目协作管理这个整体, 拆分为一个个功能完整、业务逻辑明确的业务域,如项目域、任务域、工时域等等 。每一个业务域对外提供明确的领域服务, 一个业务领域可以管理多个业务实体。



技术的挑战




在划分完领域后,理想的情况是各领域高度自治,减少依赖,甚至各领域可以由不同的团队来实现,各团队聚焦沉淀该领域核心能力。


最终,我们形成了一个组件化方案: 根据划分出来的领域,将系统拆分成业务组件(核心子领域)和基础组件(通用和支撑子领域),各组件前后端分离 。即 会有以下前端应用:需求管理、项目管理、缺陷管理、用例管理等;后端应用相应提供不同的领域服务,领域服务采用分层架构 (interface, application, domain, infrastructure) 权限管理、网关服务、消息服务等基础组件下沉,实现最大化组件复用。



按照领域拆分成业务组件, 对系统来说,最终提供给终端用户还需是一个整体。但 组件化意味着分离,那对于业务组件的前后端应用又面临怎样的协同挑战呢?


业务组件前端应用的挑战





为了实现各业务组件能并行、独立演进,理想情况下,前端子应用需满足独立编译、打包、部署,并最终集成到一个平台上呈现统一的 UI 风格和一致的交互体验。


以上业界将此归结为微前端架构:实现一种架构风格,可以将众多独立交付的前端应用组合成一个大型整体,对客户表现为一件单一完整的产品。


最终,我们行云团队落地了一个 Jmodule 微前端组件框架。



前端应用通过微前端架构和前端组件框架注册到平台,系统层实现组件元数据管理、运行时热加载静态资源和组件间通信,对用户侧提供完全可插拔可配置的组件。具体原理和实现等将在后续另一篇章节中展开。


业务组件后端应用的挑战




行云在设计之初,后端服务采用的是微服务的架构 (利用spring cloud gateway 、Eureka 等实现服务注册、网关调用等),这和 DDD 相得益彰。在核心业务组件内,领域服务按照经典分层架构 (interface, application, domain, infrastructure)来组织。


  • interface-用户界面层 :Controller、restful接口调用,或者web端UI界面、移动端UI界面、第三方服务等;

  • apllication-应用层 :对外为展现层提供各种应用功能,对内调用领域层(领域服务),应用层更像是实现某个特定场景的策略,或者流程上的编排等。其协同多个领域的服务, 实现场景和业务的隔离

  • domain-领域层 :负责表达业务概念,业务行为,业务状态以及业务规则,领域模型处于这一层,是业务软件的核心。 其提供的是一系列原子服务,在这一层提供丰富的OPEN API,是实现组件化至关重要的一步

  • infrastructure-基础层 实现业务和技术的隔离层 。一般包含:网络通讯、数据库持久化、异步消息服务、南向网关服务等。这一层在落地的时候,可以实现多种适配器adaptor 来兼容对内、对外、多云异构中间件环境。


除了界定组件内部分层的边界,还需要明确组件间的调用和依赖关系,进一步明确组件的职责。在 DDD 中相应地定义了 限界上下文之间的映射关系:


  • 合作关系: 两个上下文紧密合作的关系;

  • 客户方-供应方: 上下文之间有组织的上下游依赖;

  • 遵奉者: 下游上下文只能盲目依赖上游上下文;

  • 分离方式: 两个完全没有任何联系的上下文;

  • 共享内核: 两个上下文依赖部分共享的模型;

  • 防腐层: 一个上下文通过一些适配和转换与另一个上下文交互;

  • 开放主机服务: 定义一种协议来让其他上下文来对本上下文进行访问;

  • 事件发布订阅: 通常用于定义开放主机的协议。


在组件的调用和依赖关系上,我们可以借鉴以上映射关系的理念来落地。


举个例子,我们已经沉淀了项目组件和任务组件。假设需要实现的业务场景:当删除某个项目时,需要检查项目中是否已有进行的任务,无则删之,有则提示不能删。根据 DDD 的映射关系,任务被项目依赖,任务处在上游的位置,理想情况下它不需要知道项目业务领域删除的具体逻辑规则,同时尽量减少项目业务规则的变化所带来的影响。


于是,我们在落地的时候,淘汰了下图左侧的实现方式—— 合作关系(项目和任务网状式相互调用,我中有你,你中有我),而是在 下游项目领域加了一层适配层,来隔离业务的变化对上游的影响。 同时,也确保任务这层逻辑干净、清晰,以供更多其他组件复用。


总结




总结一下,本文大体给出了 DDD 思潮在以下方面落地上的指导意义:


  • 如何沉淀清晰可复用的业务组件?

  • 如何隔离组件间的变化对其他组件的影响?


敬请期待




之后会在后续章节中分享 DDD 在插件落地的实践,解决如下问题:


如何快速响应五花八门的定制化需求,同时保持自身不腐化?


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69912185/viewspace-2722399/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-03-06

  • 博文量
    344
  • 访问量
    183917