首页/新闻资讯/正文详情

从CRUD到DDD:复杂业务系统的架构演进实践

发布时间:2026/11/3 3:48:37 来源:云帆数科 栏目:资讯中心
从CRUD到DDD:复杂业务系统的架构演进实践
1. 从CRUD到DDD架构演进的必然选择第一次接触领域驱动设计DDD是在一个电商系统的重构项目中。当时我们的代码库已经膨胀到难以维护的地步——超过2000张数据库表业务逻辑散落在各个Service层新功能的开发周期越来越长。这让我意识到传统的CRUD模式已经无法应对复杂业务场景的挑战。CRUDCreate, Read, Update, Delete是大多数开发者最早接触的数据操作模式。它简单直接适合业务规则简单的场景。但随着系统复杂度提升CRUD架构会暴露出几个致命问题贫血模型业务逻辑分散在Service层实体对象沦为数据容器数据库驱动设计表结构直接决定业务实现技术细节与业务概念混淆SQL语句中掺杂业务规则相比之下DDD提供了一套完整的架构方法论统一语言Ubiquitous Language建立业务与技术间的沟通桥梁分层架构明确各层的职责边界领域模型将业务知识显式转化为代码结构关键区别CRUD关注数据如何存储DDD关注业务如何运作。当你的系统开始出现业务逻辑看不懂、改一处动全身的情况时就是考虑DDD的最佳时机。2. DDD核心模式解析2.1 战略设计划分问题空间战略设计解决做什么的问题核心是识别和划分业务边界。我们通过事件风暴Event Storming工作坊来实施领域Domain业务范围如电商领域的订单、支付子域Subdomain核心/支撑/通用子域划分限界上下文Bounded Context明确的语义边界在电商系统中典型的限界上下文划分| 上下文 | 职责 | 示例模型 | |---------------|-----------------------|--------------------| | 订单上下文 | 订单创建与跟踪 | Order, OrderItem | | 支付上下文 | 支付处理 | Payment, Transaction| | 库存上下文 | 库存管理 | Inventory, SKU |2.2 战术设计构建解决方案战术设计解决怎么做的问题包含以下核心模式实体Entity具有唯一标识的对象如User的userId值对象Value Object通过属性定义的对象如Address聚合根Aggregate Root一致性边界如Order是聚合根包含OrderItems领域服务Domain Service不适合放在实体中的业务逻辑仓储Repository持久化接口工厂Factory复杂对象创建以订单系统为例的领域模型实现// 聚合根 public class Order { private OrderId id; private ListOrderItem items; private OrderStatus status; public void addItem(Product product, int quantity) { // 业务规则校验 if (status ! OrderStatus.DRAFT) { throw new IllegalStateException(只能修改草稿订单); } items.add(new OrderItem(product, quantity)); } } // 值对象 public record OrderItem(Product product, int quantity) { public BigDecimal calculateAmount() { return product.getPrice().multiply(BigDecimal.valueOf(quantity)); } }3. 分层架构实践3.1 经典四层架构DDD推荐的分层架构从上到下用户接口层Interface处理用户交互REST API、页面等应用层Application协调领域对象完成用例领域层Domain核心业务逻辑基础设施层Infrastructure技术实现数据库、消息等Spring Boot中的典型包结构src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── example/ │ │ ├── application/ # 应用服务 │ │ ├── domain/ # 领域模型 │ │ ├── infrastructure/ # 基础设施 │ │ └── interfaces/ # 接口层3.2 六边形架构变体更现代的架构变体强调内外分离内部领域模型领域服务外部数据库/UI/第三方服务等适配器优势领域核心完全独立于技术实现更容易替换基础设施如切换数据库测试时可以用内存实现替代真实数据库4. 迁移实战从CRUD到DDD4.1 迁移步骤识别核心域80%价值来自20%功能建立统一语言术语表示例代码渐进式重构先从新增功能按DDD实现逐步改造历史功能上下文映射确定各上下文间关系合作关系/客户-供应商等4.2 代码改造示例改造前贫血模型Service public class OrderService { Autowired private OrderRepository repository; public void addItem(Long orderId, Long productId, int quantity) { Order order repository.findById(orderId); Product product productService.getById(productId); // 业务逻辑散落在Service中 if (order.getStatus() ! DRAFT) { throw new RuntimeException(非法状态); } OrderItem item new OrderItem(); item.setProductId(productId); item.setQuantity(quantity); order.getItems().add(item); repository.save(order); } }改造后充血模型// 领域层 public class Order { public void addItem(Product product, int quantity) { validateStatus(); items.add(new OrderItem(product, quantity)); } private void validateStatus() { if (status ! OrderStatus.DRAFT) { throw new DomainException(只能修改草稿订单); } } } // 应用层 Service public class OrderApplicationService { public void addItem(Long orderId, Long productId, int quantity) { Order order repository.findById(orderId); Product product productGateway.getById(productId); order.addItem(product, quantity); repository.save(order); } }5. 常见问题与解决方案5.1 性能优化策略懒加载问题明确聚合边界避免过大聚合使用CQRS模式分离读写模型事务管理一个事务只修改一个聚合最终一致性通过领域事件实现// 领域事件示例 public class OrderPaidEvent { private OrderId orderId; private BigDecimal amount; private LocalDateTime paidTime; } // 事件发布 order.pay(); eventPublisher.publish(new OrderPaidEvent(order));5.2 团队协作建议统一建模工具使用PlantUML绘制领域模型图代码与模型保持同步代码评审重点业务逻辑是否在领域层聚合是否保持完整性领域术语使用是否一致测试策略单元测试覆盖领域模型集成测试验证仓储实现契约测试验证上下文交互6. 进阶实践与工具链6.1 事件溯源Event Sourcing将状态变更记录为事件序列优势完整审计追踪、时间旅行调试挑战处理快照、事件版本迁移实现示例public class Order { private ListDomainEvent changes new ArrayList(); public void cancel() { apply(new OrderCancelledEvent(this.id)); } private void apply(DomainEvent event) { changes.add(event); handle(event); // 更新状态 } }6.2 CQRS模式命令查询职责分离写模型保持DDD纯度读模型优化查询性能Spring实现示例RestController RequestMapping(/orders) public class OrderQueryController { GetMapping(/{id}) public OrderView getOrder(PathVariable Long id) { return queryService.getOrderView(id); } } Service public class OrderCommandService { Transactional public void cancelOrder(Long id) { Order order repository.findById(id); order.cancel(); repository.save(order); } }6.3 现代架构组合DDD与以下架构的融合微服务每个限界上下文对应一个服务云原生使用Serverless实现领域服务响应式领域事件驱动架构技术选型建议框架Axon Framework, Spring Modulith数据库PostgreSQL支持JSONB, MongoDB消息Kafka, RabbitMQ在实施DDD的三年实践中最大的体会是不要追求完美的领域模型。DDD的本质是建立业务与技术的沟通机制模型会随着业务理解不断演进。建议从一个小而核心的限界上下文开始积累经验后再逐步扩展。记住可演进的架构比正确的架构更重要。

相关推荐

基于OpenLayers+WebGL实现十万级POI地图渲染优化
基于OpenLayers+WebGL实现十万级POI地图渲染优化

1. 项目背景与挑战去年接手一个智慧城市项目时,客户提出了一个看似简单但极具挑战性的需求:要在网页端实现一个能同时展示10万个以上POI(兴趣点)的地图系统。最初尝试用Leaflet实现,当数据量超过2万点时浏览器就开始明… · 2026/11/3 3:48:37

微信汽车租赁小程序全栈开发实践指南
微信汽车租赁小程序全栈开发实践指南

1. 项目概述:微信汽车租赁小程序的设计与实现这个毕业设计项目选择开发一款基于微信生态的汽车租赁小程序,可以说是抓住了当前两个最热门的技术风口——微信小程序开发和共享经济模式。作为计算机专业的毕业设计选题,它不仅符合当下市场需求&… · 2026/11/3 3:48:37

CCC 3.0数字钥匙规范实战:NFC/BLE/UWB架构与配对流程拆解
CCC 3.0数字钥匙规范实战:NFC/BLE/UWB架构与配对流程拆解

简介:面向汽车电子从业者、数字钥匙方案开发者与车联网安全研究者的技术规范文档,聚焦CCC(Car Connectivity Consortium)发布的Digital Key Release 3标准,帮助读者理解手机替代物理车钥匙实现解锁、启动等功能的完整技… · 2026/11/3 3:47:37

ST7305/ST7306超低功耗a-TFT驱动选型与1Hz省电解析
ST7305/ST7306超低功耗a-TFT驱动选型与1Hz省电解析

简介:这份PDF技术文档围绕Sitronix ST7305与ST7306超低功耗LCD驱动IC展开,面向电子价签、可穿戴设备及IoT终端等需要长期续航与户外可视显示的硬件设计与选型人员。文档对比两款芯片的定位:ST7306为主版本,覆盖单色720480至64色24… · 2026/11/3 4:12:44

10GB+本地数据检索性能优化实战指南
10GB+本地数据检索性能优化实战指南

1. 项目概述:大规模本地数据检索的挑战与机遇处理10GB以上的本地数据检索任务时,传统方法往往会遇到明显的性能瓶颈。我最近在开发一个本地化数据分析系统时,就深刻体会到了这一点——当数据量突破8GB后,简单的全表扫描查询耗时从… · 2026/11/3 4:12:44

TensorFlow安装指南:2024年深度学习框架选型与部署实践
TensorFlow安装指南:2024年深度学习框架选型与部署实践

先交代一句背景:前阵子有个转行做算法的朋友问我,2024 年了,入门深度学习到底选 tensorflow 还是 PyTorch?我就知道他又被网上的框架大战绕晕了。作为从 TensorFlow 1.x 时代就用它跑模型、后来又在生产环境里用 TF Serving 落地过… · 2026/11/3 4:12:44

PSS/E自定义模型接口层解析:标志位、STRTIN与USRMDL
PSS/E自定义模型接口层解析:标志位、STRTIN与USRMDL

简介:《PSSE自定义模型学习资料》面向电力系统动态仿真学习者及需在PSS/E中开发用户自定义模型的工程人员,聚焦Fortran模型子程序编写、编译调用与调试中的常见问题,帮助读者理解自定义模型从逻辑设计到接入主程序的实现路径。压缩包仅含1个d… · 2026/11/3 4:12:44

SCADA系统在工业预防性维护与能效管理中的应用
SCADA系统在工业预防性维护与能效管理中的应用

1. SCADA系统与工业运营的深度耦合在现代化工业体系中,SCADA(监控与数据采集系统)早已从简单的数据记录工具演变为支撑企业智能决策的神经中枢。我亲历过多个工业现场从传统人工巡检到数字化管控的转型过程,最深刻的体会是&#x… · 2026/11/3 4:12:44

无人机操作员认证培训全解析:市场需求与课程设计
无人机操作员认证培训全解析:市场需求与课程设计

1. 无人机操作员认证培训的市场需求分析最近两年,无人机应用场景呈现爆发式增长态势。根据行业调研数据显示,2023年国内商用无人机市场规模已突破500亿元,年增长率保持在30%以上。这种快速增长直接催生了对专业无人机操作员的海量需求&#x… · 2026/11/3 4:11:44

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 4:42:45

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 5:17:18

STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 4:42:45

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 5:17:18

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码