DDD领域驱动设计在企业级应用中的落地实践:聚合根、值对象、领域服务设计模式详解

Frank515
Frank515 2026-01-19T19:07:16+08:00
0 0 1

引言

在现代企业级应用开发中,面对日益复杂的业务需求和庞大的系统规模,传统的架构模式已经难以满足业务演进的需求。领域驱动设计(Domain-Driven Design,简称DDD)作为一种应对复杂业务场景的软件设计方法论,正在被越来越多的企业所采用。

DDD的核心思想是将业务领域的复杂性通过建模的方式抽象出来,让软件设计更好地反映业务本质。本文将深入探讨DDD在企业级应用中的实际落地实践,重点介绍聚合根、值对象、领域服务等核心概念的设计模式和实现方法。

DDD基础理论回顾

什么是领域驱动设计

领域驱动设计是由Eric Evans在其2003年出版的《Domain-Driven Design》一书中提出的软件开发方法论。它强调通过深入理解业务领域,将业务复杂性映射到软件架构中,从而构建出能够有效应对业务变化的系统。

DDD的核心理念包括:

  • 以业务领域为核心
  • 强调与业务专家的紧密协作
  • 通过模型驱动设计
  • 注重领域概念的清晰表达

DDD的核心概念

在DDD中,有几个关键概念需要理解:

领域(Domain):业务问题所在的范围,是系统要解决的实际问题。

子域(Subdomain):领域可以划分为多个子域,每个子域都有其特定的业务逻辑。

限界上下文(Bounded Context):明确划分不同领域模型的边界,确保模型的一致性。

实体(Entity):具有唯一标识的对象,其身份在生命周期中保持不变。

值对象(Value Object):没有唯一标识的对象,通过属性值来识别。

聚合根设计模式详解

什么是聚合根

聚合根是DDD中的核心概念之一。聚合根是一个实体,它定义了聚合的边界,确保聚合内部的一致性。聚合根是外部访问聚合内部其他对象的唯一入口点。

在实际应用中,聚合根通常代表业务领域中的关键概念,比如订单、客户、产品等。它们具有以下特征:

  1. 统一的生命周期:聚合内的所有对象共享相同的生命周期
  2. 强一致性保证:对聚合内数据的操作必须保持一致
  3. 单一访问点:外部只能通过聚合根访问聚合内部对象

聚合根设计原则

在设计聚合根时,需要遵循以下原则:

1. 聚合边界设计原则

// 示例:订单聚合根的设计
public class Order {
    private String orderId;          // 聚合根标识
    private Customer customer;       // 客户信息
    private List<OrderItem> items;   // 订单项列表
    private OrderStatus status;      // 订单状态
    
    // 业务方法:添加订单项
    public void addItem(Product product, int quantity) {
        // 验证业务规则
        if (status != OrderStatus.PENDING) {
            throw new IllegalStateException("只有待处理订单才能添加商品");
        }
        
        OrderItem item = new OrderItem(product, quantity);
        items.add(item);
    }
    
    // 业务方法:确认订单
    public void confirm() {
        if (items.isEmpty()) {
            throw new IllegalStateException("订单必须包含至少一个商品项");
        }
        this.status = OrderStatus.CONFIRMED;
    }
}

2. 聚合内一致性保证

聚合根确保聚合内部数据的一致性,通过以下方式实现:

public class Account {
    private String accountId;
    private BigDecimal balance;
    private List<Transaction> transactions;
    
    // 转账操作,保证原子性
    public void transferTo(Account targetAccount, BigDecimal amount) {
        if (this.balance.compareTo(amount) < 0) {
            throw new InsufficientFundsException("余额不足");
        }
        
        // 在同一个聚合内完成转账操作
        this.balance = this.balance.subtract(amount);
        targetAccount.balance = targetAccount.balance.add(amount);
        
        // 记录交易日志
        Transaction debit = new Transaction(this.accountId, amount, "DEBIT");
        Transaction credit = new Transaction(targetAccount.accountId, amount, "CREDIT");
        
        this.transactions.add(debit);
        targetAccount.transactions.add(credit);
    }
}

3. 聚合根的职责划分

public class OrderAggregate {
    private String orderId;
    private Customer customer;
    private List<OrderItem> items;
    private OrderStatus status;
    private LocalDateTime createdTime;
    
    // 聚合根的核心业务方法
    public void processOrder() {
        validateOrder();
        calculateTotal();
        updateInventory();
        notifyCustomer();
        this.status = OrderStatus.PROCESSED;
    }
    
    // 验证订单有效性
    private void validateOrder() {
        if (customer == null) {
            throw new ValidationException("客户信息不能为空");
        }
        if (items == null || items.isEmpty()) {
            throw new ValidationException("订单必须包含商品项");
        }
    }
    
    // 计算订单总金额
    private void calculateTotal() {
        BigDecimal total = items.stream()
            .map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        // 可以在这里添加折扣计算等业务逻辑
    }
    
    // 更新库存
    private void updateInventory() {
        for (OrderItem item : items) {
            item.getProduct().decreaseStock(item.getQuantity());
        }
    }
}

值对象的应用实践

值对象的核心特性

值对象是DDD中的重要概念,它具有以下特征:

  1. 不可变性:一旦创建就不能修改
  2. 无标识性:通过属性值来识别,而不是唯一标识符
  3. 完全相等性:两个值对象如果所有属性都相同,则认为是相等的

值对象设计示例

// 地址值对象
public class Address {
    private final String street;
    private final String city;
    private final String state;
    private final String zipCode;
    private final String country;
    
    public Address(String street, String city, String state, String zipCode, String country) {
        this.street = Objects.requireNonNull(street);
        this.city = Objects.requireNonNull(city);
        this.state = Objects.requireNonNull(state);
        this.zipCode = Objects.requireNonNull(zipCode);
        this.country = Objects.requireNonNull(country);
    }
    
    // getter方法
    public String getStreet() { return street; }
    public String getCity() { return city; }
    public String getState() { return state; }
    public String getZipCode() { return zipCode; }
    public String getCountry() { return country; }
    
    // 重写equals和hashCode方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Address address = (Address) o;
        return Objects.equals(street, address.street) &&
               Objects.equals(city, address.city) &&
               Objects.equals(state, address.state) &&
               Objects.equals(zipCode, address.zipCode) &&
               Objects.equals(country, address.country);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(street, city, state, zipCode, country);
    }
    
    // 重写toString方法
    @Override
    public String toString() {
        return "Address{" +
               "street='" + street + '\'' +
               ", city='" + city + '\'' +
               ", state='" + state + '\'' +
               ", zipCode='" + zipCode + '\'' +
               ", country='" + country + '\'' +
               '}';
    }
}

// 金额值对象
public class Money {
    private final BigDecimal amount;
    private final String currency;
    
    public Money(BigDecimal amount, String currency) {
        this.amount = Objects.requireNonNull(amount);
        this.currency = Objects.requireNonNull(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);
    }
    
    public Money multiply(BigDecimal multiplier) {
        return new Money(this.amount.multiply(multiplier), this.currency);
    }
    
    // getter方法
    public BigDecimal getAmount() { return amount; }
    public String getCurrency() { return currency; }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Money money = (Money) o;
        return Objects.equals(amount, money.amount) &&
               Objects.equals(currency, money.currency);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(amount, currency);
    }
}

值对象在聚合中的应用

public class Customer {
    private String customerId;
    private String name;
    private Email email;
    private Address address;
    private Phone phone;
    
    // 构造函数
    public Customer(String customerId, String name, Email email, Address address, Phone phone) {
        this.customerId = customerId;
        this.name = name;
        this.email = email;
        this.address = address;
        this.phone = phone;
    }
    
    // 更新客户信息
    public void updateContactInfo(Email newEmail, Address newAddress, Phone newPhone) {
        // 值对象的不可变性确保了数据的一致性
        this.email = newEmail;
        this.address = newAddress;
        this.phone = newPhone;
    }
    
    // getter方法
    public String getCustomerId() { return customerId; }
    public String getName() { return name; }
    public Email getEmail() { return email; }
    public Address getAddress() { return address; }
    public Phone getPhone() { return phone; }
}

领域服务设计模式

领域服务的核心概念

领域服务是DDD中用于封装那些不属于特定实体或值对象的业务逻辑的服务。当业务操作涉及多个聚合根,或者需要协调多个领域对象时,就需要使用领域服务。

领域服务的设计原则

// 订单处理领域服务
public class OrderProcessingService {
    
    private final OrderRepository orderRepository;
    private final InventoryService inventoryService;
    private final PaymentService paymentService;
    private final NotificationService notificationService;
    
    public OrderProcessingService(OrderRepository orderRepository,
                                 InventoryService inventoryService,
                                 PaymentService paymentService,
                                 NotificationService notificationService) {
        this.orderRepository = orderRepository;
        this.inventoryService = inventoryService;
        this.paymentService = paymentService;
        this.notificationService = notificationService;
    }
    
    // 处理订单的核心业务逻辑
    public Order processOrder(String orderId) {
        // 1. 获取订单
        Order order = orderRepository.findById(orderId);
        if (order == null) {
            throw new OrderNotFoundException("订单不存在: " + orderId);
        }
        
        // 2. 验证库存
        validateInventory(order.getItems());
        
        // 3. 执行支付
        PaymentResult paymentResult = paymentService.processPayment(
            order.getCustomerId(), 
            order.getTotalAmount()
        );
        
        if (!paymentResult.isSuccess()) {
            throw new PaymentException("支付失败: " + paymentResult.getErrorMessage());
        }
        
        // 4. 更新订单状态
        order.confirm();
        order.setPaymentId(paymentResult.getPaymentId());
        orderRepository.save(order);
        
        // 5. 发送通知
        notificationService.sendOrderConfirmation(order);
        
        return order;
    }
    
    private void validateInventory(List<OrderItem> items) {
        for (OrderItem item : items) {
            if (!inventoryService.hasSufficientStock(item.getProductId(), item.getQuantity())) {
                throw new InsufficientInventoryException(
                    "商品库存不足: " + item.getProductName()
                );
            }
        }
    }
}

// 订单计算领域服务
public class OrderCalculationService {
    
    public BigDecimal calculateOrderTotal(List<OrderItem> items) {
        return items.stream()
            .map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    
    public BigDecimal calculateDiscount(Order order) {
        BigDecimal total = calculateOrderTotal(order.getItems());
        
        // 根据客户等级计算折扣
        if (order.getCustomer().getLevel() == CustomerLevel.VIP) {
            return total.multiply(new BigDecimal("0.1")); // 10% 折扣
        } else if (order.getCustomer().getLevel() == CustomerLevel.GOLD) {
            return total.multiply(new BigDecimal("0.05")); // 5% 折扣
        }
        
        return BigDecimal.ZERO;
    }
    
    public BigDecimal calculateFinalAmount(Order order) {
        BigDecimal total = calculateOrderTotal(order.getItems());
        BigDecimal discount = calculateDiscount(order);
        return total.subtract(discount);
    }
}

领域服务的职责划分

// 客户管理领域服务
public class CustomerManagementService {
    
    private final CustomerRepository customerRepository;
    private final EmailValidationService emailValidationService;
    private final CustomerNotificationService notificationService;
    
    public CustomerManagementService(CustomerRepository customerRepository,
                                   EmailValidationService emailValidationService,
                                   CustomerNotificationService notificationService) {
        this.customerRepository = customerRepository;
        this.emailValidationService = emailValidationService;
        this.notificationService = notificationService;
    }
    
    // 创建客户
    public Customer createCustomer(String name, String email, Address address) {
        // 验证邮箱格式
        if (!emailValidationService.isValid(email)) {
            throw new InvalidEmailException("邮箱格式不正确: " + email);
        }
        
        // 检查邮箱是否已存在
        if (customerRepository.findByEmail(email) != null) {
            throw new DuplicateCustomerException("邮箱已被注册: " + email);
        }
        
        Customer customer = new Customer(
            generateCustomerId(),
            name,
            new Email(email),
            address,
            new Phone()
        );
        
        customerRepository.save(customer);
        notificationService.sendWelcomeEmail(customer);
        
        return customer;
    }
    
    // 更新客户信息
    public void updateCustomer(String customerId, String name, String email, Address address) {
        Customer customer = customerRepository.findById(customerId);
        if (customer == null) {
            throw new CustomerNotFoundException("客户不存在: " + customerId);
        }
        
        // 验证邮箱格式
        if (!emailValidationService.isValid(email)) {
            throw new InvalidEmailException("邮箱格式不正确: " + email);
        }
        
        customer.updateContactInfo(
            new Email(email),
            address,
            new Phone()
        );
        
        customerRepository.save(customer);
    }
    
    private String generateCustomerId() {
        return "CUST_" + System.currentTimeMillis();
    }
}

仓储模式实现

仓储的核心概念

仓储(Repository)是DDD中用于封装数据访问逻辑的模式。它为领域模型提供了一种抽象的数据访问方式,让领域层不需要关心数据持久化的具体实现。

仓储接口设计

// 基础仓储接口
public interface Repository<T> {
    T findById(String id);
    List<T> findAll();
    void save(T entity);
    void delete(T entity);
}

// 订单仓储接口
public interface OrderRepository extends Repository<Order> {
    List<Order> findByCustomerId(String customerId);
    List<Order> findByStatus(OrderStatus status);
    List<Order> findByDateRange(LocalDateTime startDate, LocalDateTime endDate);
    Page<Order> findByPage(int page, int size);
    void saveWithLock(Order order, long version);
}

// 客户仓储接口
public interface CustomerRepository extends Repository<Customer> {
    Customer findByEmail(String email);
    List<Customer> findByLevel(CustomerLevel level);
    Page<Customer> findByPage(int page, int size);
}

仓储实现示例

// 订单仓储实现
@Repository
public class OrderRepositoryImpl implements OrderRepository {
    
    private final EntityManager entityManager;
    private final JdbcTemplate jdbcTemplate;
    
    public OrderRepositoryImpl(EntityManager entityManager, JdbcTemplate jdbcTemplate) {
        this.entityManager = entityManager;
        this.jdbcTemplate = jdbcTemplate;
    }
    
    @Override
    public Order findById(String id) {
        return entityManager.find(Order.class, id);
    }
    
    @Override
    public List<Order> findAll() {
        TypedQuery<Order> query = entityManager.createQuery("SELECT o FROM Order o", Order.class);
        return query.getResultList();
    }
    
    @Override
    public void save(Order order) {
        if (order.getOrderId() == null) {
            entityManager.persist(order);
        } else {
            entityManager.merge(order);
        }
    }
    
    @Override
    public void delete(Order order) {
        Order managedOrder = entityManager.find(Order.class, order.getOrderId());
        if (managedOrder != null) {
            entityManager.remove(managedOrder);
        }
    }
    
    @Override
    public List<Order> findByCustomerId(String customerId) {
        TypedQuery<Order> query = entityManager.createQuery(
            "SELECT o FROM Order o WHERE o.customer.customerId = :customerId", 
            Order.class
        );
        query.setParameter("customerId", customerId);
        return query.getResultList();
    }
    
    @Override
    public List<Order> findByStatus(OrderStatus status) {
        TypedQuery<Order> query = entityManager.createQuery(
            "SELECT o FROM Order o WHERE o.status = :status", 
            Order.class
        );
        query.setParameter("status", status);
        return query.getResultList();
    }
    
    @Override
    public Page<Order> findByPage(int page, int size) {
        TypedQuery<Order> query = entityManager.createQuery("SELECT o FROM Order o", Order.class);
        query.setFirstResult(page * size);
        query.setMaxResults(size);
        
        List<Order> content = query.getResultList();
        long total = countTotal();
        
        return new PageImpl<>(content, PageRequest.of(page, size), total);
    }
    
    private long countTotal() {
        TypedQuery<Long> countQuery = entityManager.createQuery(
            "SELECT COUNT(o) FROM Order o", 
            Long.class
        );
        return countQuery.getSingleResult();
    }
    
    @Override
    public void saveWithLock(Order order, long version) {
        // 使用乐观锁机制
        String sql = "UPDATE orders SET status = ?, version = ? WHERE order_id = ? AND version = ?";
        int updatedRows = jdbcTemplate.update(sql, 
            order.getStatus().name(), 
            version + 1,
            order.getOrderId(),
            version
        );
        
        if (updatedRows == 0) {
            throw new OptimisticLockException("订单已被其他用户修改,请刷新页面后重试");
        }
    }
}

实际业务场景应用

电商订单系统设计案例

让我们通过一个完整的电商订单系统来展示DDD的实践应用:

// 订单聚合根
@Entity
public class Order {
    @Id
    private String orderId;
    
    @Embedded
    private Customer customer;
    
    @ElementCollection
    private List<OrderItem> items;
    
    @Embedded
    private Money totalAmount;
    
    private OrderStatus status;
    
    @Temporal(TemporalType.TIMESTAMP)
    private LocalDateTime createdTime;
    
    @Version
    private long version;
    
    // 构造函数
    public Order(String orderId, Customer customer) {
        this.orderId = orderId;
        this.customer = customer;
        this.items = new ArrayList<>();
        this.status = OrderStatus.PENDING;
        this.createdTime = LocalDateTime.now();
    }
    
    // 添加订单项
    public void addItem(Product product, int quantity) {
        if (status != OrderStatus.PENDING) {
            throw new IllegalStateException("只有待处理订单才能添加商品");
        }
        
        OrderItem item = new OrderItem(product, quantity);
        items.add(item);
        updateTotalAmount();
    }
    
    // 确认订单
    public void confirm() {
        if (items.isEmpty()) {
            throw new IllegalStateException("订单必须包含至少一个商品项");
        }
        this.status = OrderStatus.CONFIRMED;
    }
    
    // 更新总金额
    private void updateTotalAmount() {
        BigDecimal total = items.stream()
            .map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        this.totalAmount = new Money(total, "CNY");
    }
    
    // getter方法
    public String getOrderId() { return orderId; }
    public Customer getCustomer() { return customer; }
    public List<OrderItem> getItems() { return items; }
    public Money getTotalAmount() { return totalAmount; }
    public OrderStatus getStatus() { return status; }
    public LocalDateTime getCreatedTime() { return createdTime; }
}

// 订单项值对象
@Embeddable
public class OrderItem {
    private String productId;
    private String productName;
    private Money price;
    private int quantity;
    
    // 构造函数
    public OrderItem(Product product, int quantity) {
        this.productId = product.getProductId();
        this.productName = product.getName();
        this.price = product.getPrice();
        this.quantity = quantity;
    }
    
    // getter方法
    public String getProductId() { return productId; }
    public String getProductName() { return productName; }
    public Money getPrice() { return price; }
    public int getQuantity() { return quantity; }
}

// 订单状态枚举
public enum OrderStatus {
    PENDING,        // 待处理
    CONFIRMED,      // 已确认
    PROCESSING,     // 处理中
    SHIPPED,        // 已发货
    DELIVERED,      // 已送达
    CANCELLED       // 已取消
}

领域服务整合

// 订单处理领域服务
@Service
@Transactional
public class OrderDomainService {
    
    private final OrderRepository orderRepository;
    private final InventoryService inventoryService;
    private final PaymentService paymentService;
    private final NotificationService notificationService;
    
    public OrderDomainService(OrderRepository orderRepository,
                            InventoryService inventoryService,
                            PaymentService paymentService,
                            NotificationService notificationService) {
        this.orderRepository = orderRepository;
        this.inventoryService = inventoryService;
        this.paymentService = paymentService;
        this.notificationService = notificationService;
    }
    
    @Transactional
    public Order createOrder(String customerId, List<OrderItemRequest> items) {
        // 1. 验证商品库存
        validateInventory(items);
        
        // 2. 创建订单
        String orderId = generateOrderId();
        Customer customer = findCustomer(customerId);
        Order order = new Order(orderId, customer);
        
        // 3. 添加商品项
        for (OrderItemRequest itemRequest : items) {
            Product product = findProduct(itemRequest.getProductId());
            order.addItem(product, itemRequest.getQuantity());
        }
        
        // 4. 保存订单
        orderRepository.save(order);
        
        return order;
    }
    
    @Transactional
    public Order processOrder(String orderId) {
        Order order = orderRepository.findById(orderId);
        if (order == null) {
            throw new OrderNotFoundException("订单不存在: " + orderId);
        }
        
        // 1. 确认订单
        order.confirm();
        
        // 2. 预扣库存
        for (OrderItem item : order.getItems()) {
            inventoryService.reserveStock(item.getProductId(), item.getQuantity());
        }
        
        // 3. 处理支付
        PaymentResult paymentResult = paymentService.processPayment(
            order.getCustomer().getCustomerId(),
            order.getTotalAmount()
        );
        
        if (!paymentResult.isSuccess()) {
            throw new PaymentException("支付失败: " + paymentResult.getErrorMessage());
        }
        
        // 4. 更新订单状态
        order.setPaymentId(paymentResult.getPaymentId());
        orderRepository.saveWithLock(order, order.getVersion());
        
        // 5. 发送通知
        notificationService.sendOrderConfirmation(order);
        
        return order;
    }
    
    private void validateInventory(List<OrderItemRequest> items) {
        for (OrderItemRequest item : items) {
            if (!inventoryService.hasSufficientStock(item.getProductId(), item.getQuantity())) {
                throw new InsufficientInventoryException(
                    "商品库存不足: " + item.getProductId()
                );
            }
        }
    }
    
    private String generateOrderId() {
        return "ORD_" + System.currentTimeMillis();
    }
    
    private Customer findCustomer(String customerId) {
        // 实现客户查找逻辑
        return customerRepository.findById(customerId);
    }
    
    private Product findProduct(String productId) {
        // 实现产品查找逻辑
        return productRepository.findById(productId);
    }
}

最佳实践与注意事项

聚合根设计最佳实践

  1. 合理划分聚合边界:聚合应该足够小,避免过度设计;同时要足够大,保证业务操作的完整性。

  2. 避免循环依赖:聚合根之间不应该存在循环引用关系。

  3. 保持聚合内一致性:所有对聚合内对象的操作都应该是原子性的。

// 好的设计示例:合理的聚合边界划分
public class Order {
    private String orderId;
    private Customer customer;      // 客户信息(聚合根)
    private List<OrderItem> items;  // 订单项列表(聚合根)
    
    // 订单相关的业务逻辑
    public void addItem(OrderItem item) {
        // 保持聚合内一致性
        this.items.add(item);
    }
}

public class Customer {
    private String customerId;
    private String name;
    private Email email;
    
    // 客户相关业务逻辑
    public void updateEmail(Email newEmail) {
        this.email = newEmail;
    }
}

领域服务设计建议

  1. 服务粒度适中:领域服务应该专注于特定的业务领域,避免过度聚合。

  2. 避免过度封装:不要将所有逻辑都封装在领域服务中,适当的职责分离很重要。

  3. 事务边界明确:领域服务中的操作应该有明确的事务边界。

// 领域服务设计示例
@Service
public class OrderManagementService {
    
    // 专注于订单管理的业务逻辑
    public void cancelOrder(String orderId) {
        Order order = orderRepository.findById(orderId);
        if (order.getStatus() != OrderStatus.CONFIRMED) {
            throw new IllegalStateException("只有已确认的订单才能取消");
        }
        
        order.cancel();
        orderRepository.save(order);
        
        // 通知相关方
        notificationService.sendOrderCancellationNotification(order);
    }
    
    // 集成多个领域的业务逻辑
    public Order completeOrder(String orderId) {
        Order order = orderRepository.findById(orderId);
        // 实现订单完成的完整业务流程
        return processCompleteOrder(order);
    }
}

仓储模式最佳实践

  1. 接口与实现分离:仓储接口应该只定义抽象方法,具体实现可以针对不同数据源进行优化。

  2. 性能优化:合理使用缓存、批量操作等技术提升仓储性能。

  3. 异常处理:仓储层应该提供清晰的异常信息,便于上层业务逻辑处理。

// 仓储接口设计示例
public interface OrderRepository {
    // 基础CRUD操作
    Order findById(String id);
    void save(Order order);
    
    // 业务相关查询方法
    List<Order> findByCustomerId(String customerId);
    List<Order> findByStatusAndDateRange(OrderStatus status, LocalDateTime start, LocalDateTime end);
    
    // 分页查询
    Page<Order> findByPage(int page, int size
相关推荐
广告位招租

相似文章

    评论 (0)

    0/2000