标签: DDD

石昊 | 2024-06-17 | DDD

领域驱动设计DDD在B端营销系统的实践

1 背景 通过营销活动实现客户/用户拉新、留存和促活是业界普遍采用的方法。为实现商户增长和留存,美团核心本地商业/商业增值技术部也构建了相应的营销系统来支撑商户的线上营销运营。在系统建设过程中,面临着业务体量大、行业跨度大、场景多样、客户结构复杂,需求多变等挑战。本文试图还原从0到1构建面向商户的营销系统过程中,并通过DDD(领域驱动设计)来应对系统设计和建设中遇到的业务复杂度高、需求多变、维护成本大等问题。 2 基本概念 软件系统的复杂性主要体现在三个方面。 隐晦 :一是抽象层面的隐晦,抽象系统时,每个人都有自己特定的视角,你需要站在对方的角度才能明白他为什么这么做;其次是实现层面的隐晦,代码是一种技术实现,通常与现实世界的业务概念脱节,无形中增加了理解成本。 耦合 :代码层面的耦合扩大了修改范围;模块层面的耦合需要跨模块/服务交互;系统层面的耦合则需要跨团队协作。从代码到模块再到系统,耦合的影响逐渐扩大,成本随之增加。 变化 :业务需求决定了系统功能,不同的用户需求不一样,不同的业务发展阶段需求在不断变化,系...

 381 |  0 |  0 DDD

追风少年 | 2024-05-24 | DDD

万字聊一聊DDD领域驱动设计理论

一、前言 领域驱动设计简称“DDD”,一套“知易行难”的方法论。同时我所工作的这些年,尤其在某大厂做初创项目的那段时间,经常会产生各式各样的“思想碰撞”,特别在设计中台基建类领域时,为了保证充足的扩展性和稳定性,都要好好的“碰撞”一下。虽然在设计过程中,每个人的想法不尽相同,但是最终达成一致的那一刻,每个人的技术思想都会得到提升。 对于DDD,我的观点是, 它是一套非常优秀的能提升个人认知高度的方法论 。注意,我说的是个人认知,不仅是它所带来的业务和团队价值(它所带来的业务和团队价值会在下面讲)。它的战略设计方法论能很好提升技术人员的全局视野,它的战术设计方法论也能强化个人的技术细节把控力和结构性思维。除此之外,好的DDD设计也反映出一个技术人员对于业务的理解力,往往 优秀的领域专家也是半个业务专家 。 如果你一直困惑于自己究竟该如何提升技术和业务思考能力;如何提升全局视野,提升自己的结构化思维的能力;如何在写了这么多代码,做了这么多需求的情况下,补充系统化的技术理念。如果这些疑惑点你都涉及,那么理解DDD,同时按照DDD的方式去思考和建设,能够为...

 288 |  0 |  0 DDD

石昊 | 2024-03-28 | DDD

拥抱毒瘤 DDD!

牛B的人物,早已经厌倦了中英文混杂,他们更进一步,使用中英文缩写,对普通人进行降维打击。更厉害的,造就新的名词,并科普出去。 有几项技术,我从心底里鄙视和厌恶,但每次在技术方案中,都默默的把它们加进去,而且给足了它们分量。因为它们对于方案的成功与否,起着重要的概念性指导作用。 它们就是中台、低代码,以及DDD。这三个不同领域中的技术,肩负着同样的责任,那就是往死里忽悠。这三个词,很伟大,它们有一个共同点,都是很容易说服非技术但能决策的人员,然后向下铺开,非常具有营销型,是职业经理人和CTO的最爱。也是咨询类公司的最爱。 这些玩意儿,有的可以忽悠大公司,有的可以忽悠小公司,反正谁也别想逃掉。 但毒瘤如果能够为我们带来利益,当然也要拥抱。不要那么死板嘛。 当妖风袭来,比起关上窗子,我们要拥抱它,要投其所好!为什么有的人工资高,有的人升的快!有的人成为了大师!要从根本上想想原因。 概念能够升华体系 你知道么?越是职位高的人,越容易喜欢虚无缥缈的东西。拿古代的皇帝来说,有很多期望与神仙相会的,就被方士骗的死去活来。即使到最后知道被骗了,也只能偷偷的把消息封锁起来。最近看《...

 242 |  0 |  0 DDD

石昊 | 2024-03-18 | DDD后端相关

两万字浅谈 DDD 领域驱动设计

一、引言 软件开发中的挑战和问题 1. 复杂性管理: 当处理复杂业务需求时,软件系统往往变得复杂,难以理解和维护。不清晰的业务逻辑和模型使开发人员难以捕捉并准确地实现业务需求。 2. 领域专家与开发人员之间的沟通障碍: 业务专家负责提供业务需求和知识,而开发人员负责将这些需求转化为可执行的软件系统。然而,由于不同的专业背景和术语之间的差异,很难进行有效的沟通,造成开发过程中的误解和偏差。 3. 数据库驱动设计的局限性: 在传统的软件开发中,往往将数据库设计作为业务逻辑的中心。这导致了紧密耦合的 数据模型 和业务逻辑,使系统变得脆弱且难以修改和扩展。 4. 难以应对变化: 在现实世界中,业务需求会不断变化和演化。然而,传统的软件开发方法往往缺乏灵活性,难以适应这种变化。系统修改和扩展常常会引入错误和破坏现有的结构。 DDD 架构的定义和目标 当谈到领域驱动设计(Domain-Driven Design,DDD)架构时,它是一种软件设计方法,旨在帮助开发人员更好地理解和解决复杂业务领域的挑战。DDD 架构的目标是将软件设计...

 274 |  0 |  0 DDD后端相关

观云 | 2024-01-18 | DDD

DDD 四层微服务架构,开箱即用!

微服务搭建思路 大家看到的这张架构图并不是空穴来潮,它是通过不断演变出来的,我们要从DDD四层架构、微服务架构两个维度去融合理解。 这里的DDD四层架构适用于单个服务的工程架构(如图中的左下部分),就是单体应用的DDD四层架构的包划分方式。 而微服务架构,则是从整体去看,整合多个单体应用,它们之间通过应用SDK工程进行[RPC]()通讯。 微服务架构下的应用SDK 这个工程比较好理解,类似于我们传统的理解的RPC包,或者叫API包,在Maven工程里,一般定义为一个子Module,里面主要定义的是[Feign]()接口(如service.XxxFeignService),DTO对象(contract.dto.XxxRequest/XxxResponse)等等,此外还可以对FeignService返回的数据进行清洗与简单通用的封装(如util.XxxUtil),也就是说它还能封装简单的业务逻辑。 但需要特别注意:应用SDK...

 433 |  0 |  0 DDD

iron Man | 2023-12-04 | DDD后端相关

DDD死党:异构冗余模式充分发挥引擎潜力

1. 异构冗余是一种常态 我们开发的系统基本上都是“数据密集型”系统,单个工具已经不能满足应用系统的需求,总体工作被拆分成一系列能被单个工具高效完成的任务,并通过 应用代码 将它们缝合起来。应用通过 API 的方式,对外提供服务,屏蔽内部的复杂性。 很多存储引擎已经提供了对数据复制(冗余)的支持,可大幅提升引擎的吞吐和性能,但仅限于“同构冗余”,比如 MySQL 的主从复制机制: image 当读成为系统压力时,我们可以为Master构建多个 Slave 节点,将读请求从 Master 迁移至 Slave 集群,从而提升系统读请求上限。 “同构冗余” 属于技术红利,每个人都能直接享受。但,“异构冗余”则属于系统设计范畴,需要开发人员进行设计实现。 在实际工作过程中,经常出现主存储引擎无法应对的场景。比如,在一个电商平台中,以 MySQL 作为主存储引擎,你会遇到: 1. 性能瓶颈。商品详情页,需要...

 634 |  0 |  0 DDD后端相关

温酒 | 2023-11-28 | DDD后端相关

DDD死党:内存Join--将复用和扩展用到极致

1. 为什么"内存Join"是个无法绕过的话题 首先,我们先简单解释下,什么是“内存Join”。 相信大家对关系数据库的 join 语句肯定不陌生,其作用就是通过关联关系从多个表中查询数据,关联条件和数据聚合全部由 数据库服务完成。 image 而 内存 Join,简单来说就是把原本数据库帮我们完成的数据聚合操作迁移到应用服务,在应用服务的内存中完成。 image 数据库join非常简单,但随着系统的发展,内存join变得越来越重要,其核心驱动力有: 1. 微服务。微服务要求“数据资产私有化”,也就是说每个服务的数据库是私有资产,不允许其他服务的直接访问。如果需要访问,只能通过服务所提供的接口完成 2. 分库分表的限制。当数据量超过 MySQL 单实例承载能力时,通常会通...

 382 |  0 |  0 DDD后端相关

iron Man | 2023-11-22 | DDD后端相关

DDD死党:单引擎查询利器

基于索引的单表查询,是 MySQL 正确打开方式!!! 基于 QueryObject 的声明式查询,是简单查询的正确使用方式!!! 1. 应用场景 单表查询在业务开发中占比最大,是所有 CRUD Boy 的入门必备,所有人在 JavaBean 和 SQL 之间乐此不疲。 整体架构如下图所示: image 这是一个简单的分层架构,主要有: 1. 接入层:接收用户或其他服务的请求,对参数进行基本验证; 2. 服务层:执行简单的业务逻辑,比如业务验证、数据转换、数据组装等; 3. 数据访问层。在 ORM 框架基础之上完成对数据库的访问; 4. 数据库层。负责数据存储和查询; 其中 ORM 框架尤为重要,帮我们完成 对象 与 关系数据 间的相互转换。因此,不少人认为玩好 ORM 就成为了高级开发人员。而实际情况是:该部分是最枯燥、最没有技术含量的“技能”。 目前,最常见的 ORM 便是 MyBatis 和 JPA...

 469 |  0 |  0 DDD后端相关

花小染 | 2023-11-22 | DDD后端相关

DDD死党:查询模型的本质

1. 查询模型的本质 查询模型的本质就是:为不同的应用场景选择最合适的存储引擎,充分发挥各个存储引擎的优势。 在系统中,读接口的数量远超写接口,但我深信: 再简单的写也是复杂,再复杂的读也是简单。 为什么呢?因为,想做好查询只需为不同的应用场景选择最合适的存储引擎,从而充分发挥底层存储引擎的优势,然后所面对的高性能、高并发等技术问题就迎刃而解了。 如下图所示: 面对一个查询请求,我们需要: 1. 接受并解析用户请求; 2. 从各个存储引擎中获取数据; 3. 对数据进行加工,包括数据聚合、数据关联、数据转换等; 4. 将最终结果返回用户; 1.1. 常见存储引擎的特征 技术选型唯一原则: 仅仅使用它的成名之作,万万不可被花里胡哨的东西干扰你的判断。 简单列举下常见的存储引擎: ![图片](https://static.developers.pub/798ca8fbba7f44

 311 |  0 |  0 DDD后端相关

温酒 | 2023-11-16 | DDD

DDD与微服务集成的第一战役:客户端重试&服务端幂等

当一个接口从简单的内部调用升级为远程方法调用(RPC)会面临很多问题,比如: 1. 本地事务失效。在内部调用时,多个方法通常在同一事务中执行,可以使用本地数据库事务来确保数据的一致性。但是,在远程方法调用中,由于涉及到网络通信,事务的边界会扩展到多个系统之间,因此无法直接使用本地事务。如果远程方法调用出现异常,可能会导致事务提交失败,从而产生数据不一致; 2. 第三状态影响。网络不确定性可能导致远程调用无法成功获得结果,例如网络连接中断、网络超时等。在这种情况下,客户端无法获得期望的结果,调用会以网络错误或超时的方式结束; 3. 服务版本兼容性问题。如果服务接口发生变化,客户端和服务端的版本不匹配可能导致调用失败; 4. 性能问题、可用性问题、安全问题等; 由于涉及的问题比较多,这里重点分析和解决 RPC 调用时的第三状态问题。 1. 什么是第三状态 当一个客户端发起一个RPC请求时,服务端可能会返回不同的状态,包括: 1. 成功:服务端成功完成了客户端发送的请求,并返回对应的响应结果; 2. 失败:服务端无法成功处理客户端发送的请求,并返回错误信息或异常; 3. ...

 492 |  0 |  0 DDD

奈我何 | 2023-10-25 | DDD后端相关

DDD实战:应对并发挑战,五个技巧让你轻松应对

在业务开发中,事务一致性核心在于“原子性”,则并发管理的核心在于“隔离性”。 1. 原子性:一个业务操作被视为一个不可分割的逻辑单元,要么全部执行成功,要么全部失败回滚; 2. 隔离性:并发业务操作之间要相互隔离,不能互相干扰; 1. 无处不在的并发 并发管理是指在多个用户同时访问、修改同一数据时,如何保证数据的准确性、一致性和完整性的一系列管理措施。 并发无处不在是指在当前的业务系统和应用程序中,几乎所有的操作都是并发的。无论是网络请求、数据库操作、I/O读写操作等,都可能在同一时刻被多个线程或进程同时执行。这意味着在业务开发中,必须充分考虑并发处理问题,避免出现数据竞争、死锁等问题,同时合理利用多线程、协程等技术来提高系统的性能和处理能力。 1.1. 常见业务流程 首先看以下流程: image 这是一个聚合根更新操作,包括: 1. 从 DB 中加载数据; 2. 修改内存中的数据; 3. ...

 466 |  0 |  0 DDD后端相关

一纸荒年 | 2023-10-08 | DDD后端相关

DDD架构下的防御式编程:5大关卡共同保障业务数据的有效性

1. 规则验证是准确性的基础 规则验证是业务稳定性的重要保障手段,通过规则验证,可以验证和确保系统或业务逻辑的正确性和合规性,避免潜在的错误和问题。而规则的遗漏往往会伴随着线上bug的出现。 相信每个开发人员都曾面对过以下情况: 1. 未对入参进行非空判断,在执行逻辑时导致空指针异常(NullPointerException,简称NPE); 2. 未正确验证用户权限,导致未授权操作发生,普通用户也能执行该操作,最终产生安全问题; 3. 在数据被存储到数据库时,没有进行完整性验证,导致无效数据被存储; 4. 在业务逻辑中,未对可能抛出的异常进行适当的处理,导致系统无法正常运行; 5. … 可见,验证对流程极为重要,不合理的输入会导致严重的业务问题。同时错误数据的影响也比想象中的大得多: 1. 可能会导致整个写流程异常中断; 2. 错误数据入库后,会对所有的读操作造成致命的伤害; 3. 上游系统数据错误,下游系统纷纷“崩溃”; 2. 防御式编程 如何避免上述情况的发生,答案就在 防御式编程。 防御式编程(Defensive Programming)...

 364 |  0 |  0 DDD后端相关

渣渣辉 | 2023-07-05 | DDD

迄今为止最完整的DDD实践

对于一个架构师来说,在软件开发中如何降低系统复杂度是一个永恒的挑战。 01为什么需要DDD 复杂系统设计: 系统多,业务逻辑复杂,概念不清晰,有什么合适的方法帮助我们理清楚边界,逻辑和概念 多团队协同: 边界不清晰,系统依赖复杂,语言不统一导致沟通和理解困难。有没有一种方式把业务和技术概念统一,大家用一种语言沟通。例如:航程是大家所理解的航程吗? 设计与实现一致性: PRD,详细设计和代码实现天差万别。有什么方法可以把业务需求快速转换为设计,同时还要保持设计与代码的一致性? 架构统一,可复用资产和扩展性: 当前取决于开发的同学具备很好的抽象能力和高编程的技能。有什么好的方法指导我们做抽象和实现。 02DDD的价值 边界清晰的设计方法: 通过领域划分,识别哪些需求应该在哪些领域,不断拉齐团队对需求的认知,分而治之,控制规模。 统一语言: 团队在有边界的上下文中有意识地形成对事物进行统一的描述,形成统一的概念(模型)。 业务领域的知识沉淀: 通过反复论证和提炼模型,使得模型必须与...

 518 |  0 |  0 DDD

布朗熊 | 2023-06-02 | DDD

领域驱动设计DDD|从入门到代码实践

在本文中,作者将借鉴《实现领域驱动设计》的做法,介绍领域驱动设计的基本概念的同时,用一个虚拟的公司和一个虚拟的项目,把领域驱动设计进行落地实践。 背景 为什么要写这篇文章 我是从2018年开始接触领域驱动设计(DDD),当时在前辈的推荐下拜读过Eric Evans的《领域驱动设计》,这本书是领域驱动设计的开山鼻祖,但是读完后依然一头雾水,有一种不明觉厉,但是又不得其法的迷茫感。 后面我又阅读了Vaughn Vernon的《实现领域驱动设计》,跟随着作者在虚拟公司SaaSOvation下用DDD实践了CollabOvation和ProjectOvation两个虚拟项目,算是窥得了领域驱动设计的门径。但是这本书成书时间在2013年,距今已经10多年了,这其间业界技术早已发生翻天地覆的变化,书中的实践项目已经显得有些过时了。 学习领域驱动设计一路跌跌撞撞,我希望把自己的理解和思考沉淀下来,如果同时能够对你有帮助就更好了。在本文中,我将借鉴《实现领域驱动设计》的做法,介绍领域驱动设计的基本概念的同时,用一个虚拟的公司和一个虚拟的项目,把领域驱动设计进行落地实践。 ...

 1010 |  1 |  1 DDD

一纸荒年 | 2023-05-23 | 前端相关DDD

DDD在前端应用中的一些思考

DDD旨在解决业务逻辑的复杂性,而业务逻辑大部分场景下不存在于前端。但在一些复杂的应用中,前端可能需要处理一些业务逻辑,此时DDD的一些思想和方法可能有助于组织前端代码,使其更易于理解和维护。 01什么是DDD 领域驱动设计(Domain-Driven Design,简称 DDD)是一种面向对象软件设计方法,其目的是将软件系统的核心业务领域(Domain)抽象出来,并以此为 基础 进行 设计和实现 。 领域驱动设计的核心思想是将 领域模型 作为软件设计的 中心 ,通过对领域模型的深入理解和设计,提高软件系统的可维护性、可扩展性和可重用性。领域模型是描述业务领域中重要概念、实体、关系和操作的一组对象和方法的抽象表示。 02DDD主要解决什么问题 DDD旨在 解决业务逻辑的复杂性 ,而业务逻辑 大部分场景 下是不存在于前端。业务逻辑往往包含大量的业务规则和约束。这些业务规则通常是在后端实现的,因为后端需要处理数据的验证、处理、计算和存储等。 03DDD适用于前端吗 首先上面提到了DDD主要解决的是...

 876 |  1 |  1 前端相关DDD