架构进阶之路:复杂业务开发与领域驱动设计

简介: 以下是在现公司,给成员做分享的资料。业务案例来自:一文教会你如何写复杂业务代码。作者:张建飞,进行了重新整理。

以下是在现公司,给成员做分享的资料。业务案例来自:一文教会你如何写复杂业务代码。作者:张建飞,进行了重新整理。

一 业务开发职责

1.1 开发=CVS?

image.png

1.2 为什么会这样?

1、业务所限。非供应链、交易、金融等复杂业务领域,简单业务需求偏多

2、个人原因。接受需求时,只考虑局部实现,不考虑整体业务。

设计时还没有达到要求,只局限于当前需求实现这一最低要求;无法从更高一层的角度看待问题。如果当前级别的需求都存在很大的疏漏,那么到了复杂业务场景,真的有能力能够让人放心交给你来做吗?

1.3 业务真的简单吗?

上图是当前业务系统中的信息流投放与CRM交互过程。这只是CRM中的很小一部分,目前做了多家供应商支持,不同的回调码、消息结构;而且目前支持了组合,各种分支逻辑会更复杂。加上各种风控限制,供应商的稳定性问题,整体看起来,我们的业务也没有那么简单。

1.4 复杂业务场景下的设计开发

如何定义“复杂”?

image.png

1.5 基于经验的一些解决方法

二 业务案例与分析实战

2.1 背景

这里选择阿里零售通业务作为示例。领域:典型的供应链场景,涉及品牌商入驻、库存/仓储、配送、销售多个系统和环节

image.png

2.2 商品的生命周期

2.3 关键业务节点——上架

提问:从这张图,能看到哪些信息?

上图中红框标识的是一个运营操作的“上架”动作,这是非常关键的业务操作。上架之后,商品就能在零售通上面对小店进行销售了。上架操作非常关键,所以也是商品域中最复杂的业务之一,涉及很多的数据校验和关联操作

带来的问题:分支逻辑多;且结构复杂。 商品(单品),商品组/组合商品;状态、库存、佣金、运费、规格、限购、供货价、….

2.4 实现思路?

拆分:一个大service => check1(), check2(),…,createNo(), publish(),……

问题:流程如何管理?

是否需要引入流程引擎(工作流引擎):已有 or 自研的流程引擎,or 依赖于数据库配置的流程处理。 但过早考虑这些是否合理?

2.5 回归核心问题

回到商品上架的问题,这里问题核心是工具吗?是设计模式带来的代码灵活性吗?显然不是,问题的核心应该是如何分解问题和抽象问题,知道金字塔原理的应该知道,此处,我们可以使用结构化分解将问题解构成一个有层级的金字塔结构:

2.6 总结

   通过上面流程的分析,在做过程分解的时候,不要过早把太多精力放在工具和设计模式带来的灵活性上。而是应该多花时间在对问题分析,结构化分解,最后通过合理的抽象,形成合适的阶段(Phase)和步骤(Step)上。

   当问题被清楚地结构化分解之后,我们就可以很明确地通过简单的组合等手段实现业务流程。在保证实现的基础之上,再考虑工具或设计模式来提升灵活性和可扩展性。

2.7 过程分解后的两个问题

1、领域知识被割裂肢解

到目前为止做的都是过程化拆解,导致没有一个聚合领域知识(校验规则…)的地方。每个用例的代码只关心自己的处理流程,知识没有沉淀。

相同的业务逻辑会在多个用例中被重复实现,导致代码重复度高,即使有复用,最多也就是抽取一个 util,代码对业务语义的表达能力很弱,从而影响代码的可读性和可理解性。

2、代码的业务表达能力缺失

试想下,在过程式的代码中,所做的事情无外乎就是取数据 -- 做计算 -- 存数据,在这种情况下,要如何通过代码显性化的表达业务呢? 说实话,很难做到,因为缺失了模型,以及模型之间的关系。脱离模型的业务表达,是缺少韵律和灵魂的。【人话:赋予代码业务更强的表达能力,提升可读性、可维护性】

2.8 怎么做?

举个例子,在上架过程中,有一个校验是检查库存的,其中对于组合商品(CombineBackOffer)其库存的处理会和普通商品不一样。原来的代码写法:

引入领域模型:

image.png

使用模型的表达要清晰易懂很多,而且也不需要做关于组合商品的判断了,因为我们在系统中引入了更加贴近现实的对象模型(CombineBackOffer 继承 BackOffer),通过对象的多态可以消除我们代码中的大部分的 if-else。

三 复杂业务开发方法总结

3.1 总结:过程分解+对象模型 上下结合

所谓上下结合,是指我们要结合自上而下的过程分解和自下而上的对象建模,螺旋式的构建我们的应用系统。这是一个动态的过程,两个步骤可以交替进行、也可以同时进行。

这两个步骤是相辅相成的,上面的分析可以帮助我们更好的理清模型之间的关系,而使用模型表达可以提升我们代码的复用度和业务语义表达能力

四 领域驱动设计初探

4.1 领域驱动设计的一些基础概念

领域:本质上是一种边界划分,领域词语中的“域”也是边界的意思。

领域设计= 边界 + 设计。要求:具备领域知识、总结和概括能力、达成共同认知。

电商系统,有商品模型,但是一个商品模型只有商品的基本信息,数据。如果需要获取一个商品的总价,那么我们需要调用model里面的一个方法来计算。这就是典型的贫血模型。

如果我们在商品模型里面提供一个计算总价的方法。把数据和业务逻辑放在一起,这就是充血模型。

领域模型的基础是对象模型,对象是由属性和方法组成的。识别贫血模型有一个重要的指标是:模型自身需要处理的业务逻辑是否外漏

如果模型本身没有需要处理的业务逻辑,只包含属性那么他不应该称为贫血模型。

如果模型自身需要处理业务逻辑但是没有处理,而是由调用者来处理本属于模型本身的业务逻辑时就应该称之为贫血模型。

在处理表单数据校验时,通常使用的是外部校验方式

领域设计不是一件简单事情,首先你得有这个领域的知识,然后还有一套你对这个领域知识总结和概括,甚至摸清了领域中的逻辑关系,一般人不一定掌握得好,大概只有多年业务专家才会有这个本事,或者多年来一直在开发某个业务系统,直至公司人员组织结构都按照业务领域划分成不同部门了,比如电商公司有订单组、仓库组、支付组和货运组,这种带有业务性质的组织部门其实已经代表了大家的共同领域认识。

4.2 领域驱动实践历程

1. 套概念阶段

了解了一些 概念,然后在设计中“使用”聚合根,有界上下文等概念。更进一步,也会使用一定的分层策略。然而这种做法一般对复杂度的治理并没有多大作用。

2. 融会贯通阶段

DDD 的本质是统一语言、边界划分和面向对象分析的方法。

哪些能力应该放在 Domain 层,是不是按照DDD传统的做法,将所有的业务都收拢到 Domain 上,这样做合理吗?这并不是一个可以很容易说清楚的问题。因为在现实业务中,很多的功能都是用例特有的,如果盲目的使用 Domain 收拢业务并不见得能带来多大的益处。相反,这种收拢会导致 Domain 层的膨胀过厚,反而会影响复用性和表达能力。

所以,我们考虑逐步地进行能力下沉的方式,即不强求一次就能设计出 Domain 的能力,也不强制要求把所有的业务功能都放到 Domain 层,而是采用实用主义的态度,即只对那些需要在多个场景中需要被复用的能力进行抽象下沉,而不需要复用的,就暂时放在 App 层的 Use Case 里就好了。

通过实践,发现这种循序渐进的能力下沉策略,应该是一种更符合实际、更敏捷的方法。因为我们承认模型不是一次性设计出来的,而是迭代演化出来的。

4.3 能力下沉过程

五 开发的选择:技术 or 业务

   很多业务技术同学的困惑,也是我之前的困惑:即业务技术到底是在做业务,还是做技术?业务技术的技术性体现在哪里?

   通过上面的案例,我们可以看到业务所面临的复杂性并不亚于底层技术,要想写好业务代码也不是一件容易的事情。业务技术和底层技术人员唯一的区别是他们所面临的问题域不一样。

   业务技术面对的问题域变化更多、面对的人更加庞杂。而底层技术面对的问题域更加稳定、但对技术的要求更加深。比如,如果你需要去开发 Pandora,你就要对 Class Loader 有更加深入的了解才行。

   但是不管是业务技术还是底层技术人员,有一些思维和能力都是共通的。比如,分解问题的能力,抽象思维,结构化思维等等。这些,都需要我们在日常的工作生活中不断的加深思考,沉淀能力。

相关文章
|
1月前
|
监控 Java 持续交付
后端开发中的微服务架构实践与挑战####
在当今快速迭代的软件开发领域,微服务架构以其灵活性和可扩展性成为众多企业的首选。本文探讨了微服务架构的核心概念、实施策略及面临的主要挑战,旨在为后端开发者提供一个全面的指南。通过分析真实案例,揭示微服务在提升系统敏捷性的同时,如何有效应对分布式系统的复杂性问题。 ####
|
26天前
|
消息中间件 API 持续交付
后端开发中的微服务架构实践####
【10月更文挑战第21天】 本文深入探讨了微服务架构在后端开发中的应用,从基本概念出发,详细阐述了微服务的核心优势、设计原则及关键技术。通过实际案例分析,揭示了微服务如何助力企业应对复杂业务需求,提升系统的可扩展性、灵活性与可靠性。同时,也指出了实施微服务过程中可能面临的挑战,并提供了相应的解决方案和最佳实践。 ####
28 3
|
1月前
|
API 持续交付 开发者
后端开发中的微服务架构实践与挑战
在数字化时代,后端服务的构建和管理变得日益复杂。本文将深入探讨微服务架构在后端开发中的应用,分析其在提高系统可扩展性、灵活性和可维护性方面的优势,同时讨论实施微服务时面临的挑战,如服务拆分、数据一致性和部署复杂性等。通过实际案例分析,本文旨在为开发者提供微服务架构的实用见解和解决策略。
|
29天前
|
运维 监控 负载均衡
动态服务管理平台:驱动微服务架构的高效引擎
动态服务管理平台:驱动微服务架构的高效引擎
26 0
|
4天前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
23 3
|
28天前
|
消息中间件 监控 持续交付
后端开发中的微服务架构设计与实践####
在当今快速发展的软件开发领域,微服务架构已成为构建高效、可扩展和易于维护应用的关键策略。本文将深入探讨微服务架构的核心概念、设计原则与实战技巧,通过实例解析如何在后端开发中有效实施微服务,以应对复杂业务需求和技术挑战。我们将从微服务的拆分策略、通信机制、数据管理到持续集成/持续部署(CI/CD)流程,全面剖析其背后的技术细节与最佳实践,为读者提供一份详尽的微服务架构设计与实践指南。 ####
|
18天前
|
运维 监控 Java
后端开发中的微服务架构实践与挑战####
在数字化转型加速的今天,微服务架构凭借其高度的灵活性、可扩展性和可维护性,成为众多企业后端系统构建的首选方案。本文深入探讨了微服务架构的核心概念、实施步骤、关键技术考量以及面临的主要挑战,旨在为开发者提供一份实用的实践指南。通过案例分析,揭示微服务在实际项目中的应用效果,并针对常见问题提出解决策略,帮助读者更好地理解和应对微服务架构带来的复杂性与机遇。 ####
|
17天前
|
消息中间件 运维 安全
后端开发中的微服务架构实践与挑战####
在数字化转型的浪潮中,微服务架构凭借其高度的灵活性和可扩展性,成为众多企业重构后端系统的首选方案。本文将深入探讨微服务的核心概念、设计原则、关键技术选型及在实际项目实施过程中面临的挑战与解决方案,旨在为开发者提供一套实用的微服务架构落地指南。我们将从理论框架出发,逐步深入至技术细节,最终通过案例分析,揭示如何在复杂业务场景下有效应用微服务,提升系统的整体性能与稳定性。 ####
31 1
|
22天前
|
监控 Serverless 云计算
探索Serverless架构:开发实践与优化策略
本文深入探讨了Serverless架构的核心概念、开发实践及优化策略。Serverless让开发者无需管理服务器即可运行代码,具有成本效益、高可扩展性和提升开发效率等优势。文章还详细介绍了函数设计、安全性、监控及性能和成本优化的最佳实践。
|
18天前
|
消息中间件 运维 API
后端开发中的微服务架构实践####
本文深入探讨了微服务架构在后端开发中的应用,从其定义、优势到实际案例分析,全面解析了如何有效实施微服务以提升系统的可维护性、扩展性和灵活性。不同于传统摘要的概述性质,本摘要旨在激发读者对微服务架构深度探索的兴趣,通过提出问题而非直接给出答案的方式,引导读者深入
37 1
下一篇
DataWorks