深入理解 DDD(领域驱动设计)思想

简介: 领域驱动设计(DDD)是一种以业务为核心的软件开发方法,通过限界上下文、聚合、实体、值对象等模型,分离业务与技术复杂性,提升系统可维护性与扩展性,尤其适用于复杂业务系统的架构设计。

深入理解 DDD(领域驱动设计)思想

领域驱动设计(Domain-Driven Design,DDD)是由Eric Evans在2003年提出的一种软件开发方法论,旨在通过深入理解业务领域来指导软件架构设计。DDD强调将复杂的业务逻辑封装在领域模型中,通过清晰的分层架构和战略设计模式,构建可维护、可扩展的企业级应用。

DDD核心概念

DDD的核心在于将业务领域的复杂性与技术实现的复杂性分离,通过建立清晰的领域模型来表达业务逻辑。它不仅是一种设计模式,更是一种思维方式和开发哲学。

核心术语

术语 定义
领域(Domain) 业务问题的范围和上下文
领域模型(Domain Model) 对业务领域的抽象表示
实体(Entity) 具有唯一标识的对象
值对象(Value Object) 通过属性值定义的对象
聚合(Aggregate) 一组相关对象的集合
仓储(Repository) 领域对象的持久化机制
领域服务(Domain Service) 无状态的业务逻辑

战略设计模式

限界上下文(Bounded Context)

限界上下文是DDD中最重要的概念之一,它定义了领域模型的应用范围和边界。每个限界上下文都有自己的领域模型、术语和规则。

// 电商系统中的限界上下文示例
Customer Management Context
Order Management Context
Inventory Management Context
Payment Processing Context

上下文映射(Context Mapping)

不同限界上下文之间需要进行协作,上下文映射定义了它们之间的交互方式:

  • 共享内核(Shared Kernel)
  • 客户-供应商(Customer-Supplier)
  • 遵奉者(Conformist)
  • 防腐层(Anti-Corruption Layer)

战术设计模式

实体(Entity)

实体是具有唯一标识和生命周期的对象,其标识在系统中保持不变:

public class Customer {
   
    private CustomerId id;
    private String name;
    private Email email;

    public void updateEmail(Email newEmail) {
   
        this.email = newEmail;
    }
}

值对象(Value Object)

值对象通过属性值来定义,没有唯一标识,是不可变的:

public class Address {
   
    private String street;
    private String city;
    private String zipCode;

    public boolean equals(Object other) {
   
        // 基于属性值的相等性比较
    }
}

聚合(Aggregate)

聚合是一组相关对象的集合,由聚合根统一管理:

public class Order {
   
    private OrderId id;
    private List<OrderItem> items;
    private OrderStatus status;

    public void addItem(Product product, int quantity) {
   
        // 业务规则验证
        if (status != OrderStatus.DRAFT) {
   
            throw new IllegalStateException("Cannot add items to non-draft order");
        }
        items.add(new OrderItem(product, quantity));
    }
}

领域服务

当业务逻辑不适合放在实体或值对象中时,使用领域服务:

public class OrderService {
   
    public void processOrder(Order order) {
   
        if (inventoryService.isAvailable(order.getItems())) {
   
            order.confirm();
            paymentService.processPayment(order);
        }
    }
}

分层架构

DDD采用清晰的分层架构,每层有明确的职责:

四层架构

  1. 用户接口层(Presentation Layer):处理用户交互
  2. 应用层(Application Layer):协调业务流程
  3. 领域层(Domain Layer):核心业务逻辑
  4. 基础设施层(Infrastructure Layer):技术实现细节
// 应用服务示例
public class OrderApplicationService {
   
    private OrderRepository orderRepository;
    private InventoryService inventoryService;

    public void placeOrder(OrderRequest request) {
   
        Order order = new Order(request.getCustomerId());
        order.addItems(request.getItems());

        if (inventoryService.checkAvailability(order)) {
   
            orderRepository.save(order);
        }
    }
}

领域事件

领域事件用于处理业务流程中的异步操作和系统解耦:

public class OrderPlacedEvent {
   
    private OrderId orderId;
    private CustomerId customerId;
    private List<Item> items;
}
// 事件处理器
@Component
public class InventoryEventHandler {
   
    @EventListener
    public void handle(OrderPlacedEvent event) {
   
        inventoryService.reserveItems(event.getItems());
    }
}

实体关系建模

聚合设计原则

  • 聚合根负责维护聚合内部的一致性
  • 聚合边界应该保护业务规则不变量
  • 聚合之间通过标识符引用,而不是对象引用
// 订单聚合示例
public class Order {
   
    private OrderId id;
    private CustomerId customerId;
    private List<OrderItem> items;
    private OrderStatus status;

    public void addProduct(Product product, int quantity) {
   
        // 验证业务规则
        validateProductAvailability(product, quantity);
        items.add(new OrderItem(product, quantity));
    }

    private void validateProductAvailability(Product product, int quantity) {
   
        if (quantity > product.getAvailableQuantity()) {
   
            throw new InsufficientStockException();
        }
    }
}

领域服务设计

领域服务用于处理跨多个实体的业务逻辑:

public class PricingService {
   
    public Money calculateTotal(Order order) {
   
        return order.getItems().stream()
            .map(item -> item.getPrice().multiply(item.getQuantity()))
            .reduce(Money.ZERO, Money::add);
    }
}

仓储模式

仓储模式提供领域对象的持久化机制:

public interface OrderRepository {
   
    Order findById(OrderId id);
    void save(Order order);
    List<Order> findByStatus(OrderStatus status);
}
// 实现示例
@Repository
public class JpaOrderRepository implements OrderRepository {
   
    @Override
    public Order findById(OrderId id) {
   
        return entityManager.find(Order.class, id.getValue());
    }

    @Override
    public void save(Order order) {
   
        entityManager.persist(order);
    }
}

应用服务模式

应用服务协调多个领域对象和外部服务:

@Service
public class OrderApplicationService {
   
    private OrderRepository orderRepository;
    private CustomerService customerService;
    private PaymentService paymentService;

    @Transactional
    public OrderId placeOrder(PlaceOrderCommand command) {
   
        Customer customer = customerService.findById(command.getCustomerId());
        Order order = new Order(customer.getId(), command.getItems());

        // 领域逻辑验证
        order.validate();

        // 处理支付
        PaymentResult paymentResult = paymentService.processPayment(
            order.getTotalAmount(), command.getPaymentInfo());

        if (paymentResult.isSuccess()) {
   
            order.confirm();
            orderRepository.save(order);
            return order.getId();
        } else {
   
            order.cancel();
            throw new PaymentFailedException();
        }
    }
}

工厂模式

复杂对象的创建使用工厂模式:

public class OrderFactory {
   
    public static Order createOrder(Customer customer, List<OrderItem> items) {
   
        Order order = new Order();
        order.setId(new OrderId(UUID.randomUUID()));
        order.setCustomerId(customer.getId());
        order.setItems(items);
        order.setStatus(OrderStatus.DRAFT);
        order.setCreatedAt(Instant.now());
        return order;
    }
}

领域事件模式

领域事件实现松耦合的系统架构:

// 领域事件定义
public class OrderConfirmedEvent {
   
    private final OrderId orderId;
    private final CustomerId customerId;

    public OrderConfirmedEvent(OrderId orderId, CustomerId customerId) {
   
        this.orderId = orderId;
        this.customerId = customerId;
    }
}

// 领域事件发布
public class Order {
   
    private List<DomainEvent> events = new ArrayList<>();

    public void confirm() {
   
        this.status = OrderStatus.CONFIRMED;
        events.add(new OrderConfirmedEvent(this.id, this.customerId));
    }

    public List<DomainEvent> getEvents() {
   
        return new ArrayList<>(events);
    }

    public void clearEvents() {
   
        events.clear();
    }
}

CQRS模式

命令查询职责分离(CQRS)模式分离读写操作:

// 命令模型
public class OrderCommandService {
   
    public void createOrder(CreateOrderCommand command) {
   
        Order order = new Order(command.getCustomerId());
        order.addItems(command.getItems());
        orderRepository.save(order);
    }
}

// 查询模型
public class OrderQueryService {
   
    public OrderDTO getOrder(OrderId id) {
   
        // 直接查询优化后的数据
        return orderViewRepository.findById(id);
    }
}

最佳实践

命名规范

  • 使用业务术语命名类和方法
  • 避免技术术语污染领域模型
  • 保持命名的一致性和清晰性

测试策略

  • 为领域模型编写单元测试
  • 验证业务规则的正确性
  • 使用行为驱动开发(BDD)方法

重构原则

  • 保持领域模型的纯净性
  • 避免技术细节污染领域层
  • 定期重构以保持模型的准确性

微服务中的DDD

DDD与微服务架构天然契合:

  • 每个微服务对应一个或多个限界上下文
  • 服务间通过API和事件进行通信
  • 保持服务的高内聚和低耦合

总结

DDD是一种强大的软件设计方法论,它通过深入理解业务领域来指导系统架构设计。成功的DDD实施需要技术团队和业务团队的紧密合作,以及对领域知识的持续学习和提炼。在复杂的业务系统中,DDD能够帮助我们构建清晰、可维护、可扩展的软件架构。



关于作者



🌟 我是suxiaoxiang,一位热爱技术的开发者

💡 专注于Java生态和前沿技术分享

🚀 持续输出高质量技术内容



如果这篇文章对你有帮助,请支持一下:




👍 点赞


收藏


👀 关注



您的支持是我持续创作的动力!感谢每一位读者的关注与认可!


目录
相关文章
|
3月前
|
存储 设计模式 NoSQL
ddd领域驱动设计
领域驱动设计(DDD)是一种应对复杂软件系统的思维革命与系统方法。它通过“通用语言”统一团队认知,运用“限界上下文”划分业务边界,结合“聚合”“领域事件”等战术模式,精准构建业务模型。DDD不仅提升软件对业务的映射能力,更为微服务架构提供科学的边界划分依据,是打造高内聚、低耦合系统的核心方法论。
|
存储 关系型数据库 数据库
聊多版本并发控制(MVCC)
MVCC是数据库并发控制技术,用于减少读写冲突。它维护数据的多个版本,使事务能读旧数据而写新数据,无需锁定记录。当前读获取最新版本,加锁防止修改;快照读不加锁,根据读取时的读视图(readview)决定读哪个版本。InnoDB通过隐藏字段(DB_TRX_ID, DB_ROLL_PTR)和undo log存储版本,readview记录活跃事务ID。读已提交每次读取都创建新视图,可重复读则在整个事务中复用一个视图,确保一致性。MVCC通过undo log版本链和readview规则决定事务可见性,实现了非阻塞并发读。
873 5
聊多版本并发控制(MVCC)
|
2月前
|
人工智能 测试技术 开发工具
如何将 AI 代码采纳率从30%提升到80%?
AI编码采纳率低的根本原因在于人类期望其独立完成模糊需求,本文提出了解决之道,讲解如何通过结构化文档和任务拆解提高AI的基础可靠性。
946 24
|
2月前
|
存储 人工智能 自动驾驶
云栖重磅合集 | 吴泳铭:超级人工智能之路
吴泳铭在云栖大会发表演讲,指出AGI已成必然,终极目标是超级人工智能ASI。阿里云发布通义千问7款新模型,升级全栈AI体系,推出磐久128超节点、HPN 8.0网络等基础设施,全力推进AI技术发展。
云栖重磅合集 | 吴泳铭:超级人工智能之路
|
1月前
|
缓存 NoSQL 关系型数据库
MySQL 与 Redis 如何保证双写一致性?
我是小假 期待与你的下一次相遇 ~
348 7
|
2月前
|
监控 安全 API
什么是API?进行API对接的5大常见误区!
API是软件间通信的桥梁,API对接则实现系统间数据互通。广泛应用于内外部系统集成,提升效率、降低成本、增强竞争力。本文详解其概念、场景、方法及常见误区。
什么是API?进行API对接的5大常见误区!
|
存储 缓存 NoSQL
Redis 服务器全方位介绍:从入门到核心原理
Redis是一款高性能内存键值数据库,支持字符串、哈希、列表等多种数据结构,广泛用于缓存、会话存储、排行榜及消息队列。其单线程事件循环架构保障高并发与低延迟,结合RDB和AOF持久化机制兼顾性能与数据安全。通过主从复制、哨兵及集群模式实现高可用与横向扩展,适用于现代应用的多样化场景。合理配置与优化可显著提升系统性能与稳定性。
297 0
|
1月前
|
存储 消息中间件 Kafka
Confluent 首席架构师万字剖析 Apache Fluss(三):湖流一体
原文:https://jack-vanlightly.com/blog/2025/9/2/understanding-apache-fluss 作者:Jack Vanlightly 翻译:Wayne Wang@腾讯 译注:Jack Vanlightly 是一位专注于数据系统底层架构的知名技术博主,他的文章以篇幅长、细节丰富而闻名。目前 Jack 就职于 Confluent,担任首席技术架构师,因此这篇 Fluss 深度分析文章,具备一定的客观参考意义。译文拆成了三篇文章,本文是第二篇。
349 25
Confluent 首席架构师万字剖析 Apache Fluss(三):湖流一体
|
1月前
|
人工智能 运维 Java
Spring AI Alibaba Admin 开源!以数据为中心的 Agent 开发平台
Spring AI Alibaba Admin 正式发布!一站式实现 Prompt 管理、动态热更新、评测集构建、自动化评估与全链路可观测,助力企业高效构建可信赖的 AI Agent 应用。开源共建,现已上线!
3168 45