通俗地讲述DDD的设计

通俗地讲述DDD的设计

前言

平时我们在谈论到DDD(驱动领域设计)的时候,往往感觉讳莫如深,特别是市面上对于它的定义、落地实现策略这些,都没有明确的解释,似乎一百个人有一百种解释,以至于我们在设计架构层级以及具体代码实现时,都不会用到DDD的设计思想,于是本文会按笔者理解DDD的概念以及设计原则去通俗描述,尽量让诸位培养成下意识使用它的习惯;

为什么要使用DDD

在传统分层架构(API层-业务层-Service层-DAO层)实践中,我们常遇到以下典型问题:

​​Service层相互调用导致的链式灾难​​(如A->B->C->D的深度调用)

​​Common模块过度抽象引发的架构退化​​(业务层公共代码下沉导致Service层失去业务语义)

​​调用关系失控​​(业务调用可能意外穿透到DAO层,层级边界模糊)

这些问题的本质是​​业务逻辑与技术实现耦合度过高​​,而领域驱动设计(Domain-Driven Design)为解决这些问题提供了新的视角。

DDD架构分层重构实践

javascript 复制代码
// 示例包结构
com.example
├── api        // API层:接口定义、DTO转换
├── application // 业务层:业务流程编排
├── domain     // 领域层:核心业务逻辑
└── infra      // 基础设施层:数据库/外部服务访问

API层​​ :定义对外契约,完成DTO与领域对象的双向转换。建议采用门面模式隔离外部参数与内部模型。

​​业务层​​ :编排领域服务,处理跨领域协作。此处应保持无状态,仅包含流程控制逻辑。

​​领域层​​ :封装业务规则(对于某一功能具体的代码实现),通过聚合根维护领域完整性。建议每个领域模块独立成包(如order/payment)。
​​DAO层 ​​:重构为基础设施层,实现仓储接口,支持多数据源适配。
注意:ddd的事务管理应该放在业务层,还是领域层,各有各的风险 ,业务层因为是编排调用多个服务,就会有长事务的问题,而在领域层则是有一致性问题;(因为如果把事物放在application层,增删改之间掺杂比较耗时的其他操作就会造成大事物。放在domain层,其他领域可能会有关联)

关键问题解决方案

通过​​领域事件机制​​解耦服务依赖:

javascript 复制代码
// 订单创建后发布领域事件
public class OrderService {
    @Transactional
    public void createOrder(Order order) {
        orderRepository.save(order);
        eventPublisher.publish(new OrderCreatedEvent(order.getId()));
    }
}

// 库存服务监听事件
@Component
public class InventoryHandler {
    @EventListener
    public void handle(OrderCreatedEvent event) {
        inventoryService.lockStock(event.getOrderId());
    }
}

防止逻辑下沉

建立​​分层防护机制​​:

在领域层定义仓储接口

基础设施层实现具体仓储

通过依赖注入控制反转

javascript 复制代码
// 领域层定义接口
public interface OrderRepository {
    Order findById(OrderId id);
}

// 基础设施层实现
@Repository
public class JpaOrderRepository implements OrderRepository {
    // 具体实现
}

领域划分

ddd的精华就是在于领域划分,而领域模型的设计目的

1、业务和代码要对齐,不至于一个简单的业务,要用成堆的代码解决,还要回想整个代码流程才明白这个业务;

2、让测试、开发、产品对某一个bug的描述要一致;

3、减少修改难度和影响面;
说明:

聚合根:就是bo、vo、do这些不同层有自己的返回对象类;

领域调用其他领的中间会有一个防腐层(防腐层是指对参数的转换,把这个参数转换抽取出来,传递的就是聚合根,有了防腐层是为了防止腐化其他领域的代码)

电商场景下的领域划分

┌──────────────┐ ┌─────────────┐

│ 订单域 │◄─────►│ 支付域 │

│ - 订单创建 │ │ - 支付处理 │

│ - 订单状态机 │ └─────────────┘

└───────┬──────┘

┌──────────────┐

│ 库存域 │

│ - 库存扣减 │

│ - 库存预警 │

└──────────────┘

不同层级之间传递参数,要注意转换和收敛,就是上层调用多个下层,也不要直接一个参数对象从头走到尾,而是将对象所需属性转换成需要相应的对象;

结语

DDD的真正价值在于​​建立业务与技术的统一语言​​。建议采用渐进式改造:

从核心子域开始试点

建立领域字典统一术语

通过持续重构优化模型

技术架构的演进永无止境,但通过DDD建立的清晰领域边界,能使系统在业务快速变化中保持足够的弹性。

完结撒花,如有需要收藏的看官,顺便也用发财的小手点点赞哈,如有错漏,也欢迎各位在评论区评论!

相关推荐
城管不管16 小时前
重生——第十次面试之开源中国一面挂
java·linux·开发语言·算法·面试·职场和发展·开源
Java小白笔记16 小时前
Windows系统免软件命令激活
java·网络·人工智能·windows·ai·ai编程
爱敲键盘的猴子16 小时前
深入理解 Java HashMap
java·hashmap
霸道流氓气质16 小时前
Java开发者AI编程常用MCP、Skills、Rules全景汇总
java·开发语言·ai编程
天涯醉青楼16 小时前
Spring Boot 接口返回 Bean 时字段名“变形”的深度剖析与解决方案
java
zoujiahui_201817 小时前
Python 包与环境管理工具 uv
开发语言·python·uv
步行cgn17 小时前
MyBatis 高级映射与延迟加载完全指南
java·tomcat·mybatis
thefool11226617 小时前
从中序与后序遍历序列构造二叉树
java
吴声子夜歌17 小时前
Java面试题——JVM(二)
java·开发语言·jvm
CRMEB17 小时前
商城大促活动策划全流程:从定目标到复盘四阶段
java·开发语言·人工智能·ai·开源·php