限界上下文案例

wen java案例 2

本文目录导读:

限界上下文案例

  1. 什么是限界上下文?
  2. 经典案例:电商系统
  3. 进阶案例:金融系统
  4. 常见集成模式(Context Mapping)
  5. 实际落地建议

我来为你详细讲解限界上下文(Bounded Context)的概念,并通过几个经典的案例来帮助你理解。

什么是限界上下文?

一句话解释:限界上下文是领域驱动设计(DDD)中的核心概念,指的是一个明确边界内的业务模型,在这个边界内,每个业务术语都有明确且唯一的含义。

核心要点

  • 每个上下文有自己的通用语言(Ubiquitous Language)
  • 同一个概念在不同上下文中可能有不同含义
  • 边界清晰,避免概念混淆

经典案例:电商系统

这是最典型的案例,让我们看看“订单”这个概念在不同上下文中的差异。

1 电商系统的上下文划分

┌─────────────────────────────────────────────────┐
│              电商系统                             │
├──────────┬──────────┬──────────┬────────────────┤
│ 销售上下文 │ 库存上下文 │ 物流上下文 │ 支付上下文     │
├──────────┼──────────┼──────────┼────────────────┤
│ 订单管理   │ 库存管理  │ 配送管理  │ 交易处理       │
│ 促销管理   │ 商品管理  │ 运输跟踪  │ 退款处理       │
└──────────┴──────────┴──────────┴────────────────┘

2 各上下文中的“订单”含义

上下文 “订单”的含义 关注点 核心属性
销售上下文 购物车的结算结果 商品组合、优惠、总额 商品列表、优惠券、应付金额
库存上下文 待出库的商品清单 库存扣减、缺货 商品SKU、数量、仓库位置
支付上下文 待支付的交易凭证 支付流程、退款 支付金额、支付状态、支付方式
物流上下文 待配送的包裹 配送时效、运输 收件人、地址、包裹重量

3 具体代码示例

// 销售上下文中的订单
public class Order {
    private Long id;
    private List<OrderItem> items;
    private Money totalAmount;
    private Discount discount;
    private Customer customer;
    public Money calculateTotal() {
        // 计算商品金额 - 优惠
        return items.stream()
            .map(OrderItem::getSubtotal)
            .reduce(Money.ZERO, Money::add)
            .subtract(discount.getAmount());
    }
}
// 库存上下文中的订单(实际上是出库单)
public class PickingOrder {
    private Long id;
    private List<PickingItem> pickingItems;
    private WarehouseLocation location;
    private PickingStatus status;
    public void allocateInventory() {
        // 分配库存,锁定商品
    }
}
// 支付上下文中的订单(实际上是支付单)
public class PaymentOrder {
    private String paymentId;
    private Long originOrderId;  // 引用销售订单ID
    private Money amount;
    private PaymentMethod method;
    private PaymentStatus status;
    public void executePayment() {
        // 执行支付
    }
}

进阶案例:金融系统

1 银行系统的上下文地图

┌────────────────────────────────────────────────────────┐
│                   银行系统                              │
├──────────────┬──────────────┬──────────────┬───────────┤
│   账户上下文   │   信贷上下文   │   风控上下文   │ CRM上下文 │
├──────────────┼──────────────┼──────────────┼───────────┤
│ 客户账户管理   │ 贷款审批      │ 风险评估      │ 客户关系   │
│ 存款、取款    │ 信用额度      │ 欺诈检测      │ 营销活动   │
│ 账户流水     │ 还款计划      │ 反洗钱       │ 客户画像   │
└──────────────┴──────────────┴──────────────┴───────────┘

2 关键概念的多重含义

“客户”在不同上下文中的表示:

// 账户上下文 - 关注财务信息
public class AccountHolder {
    private String accountId;
    private String name;
    private String idNumber;
    private List<Account> accounts;
    public boolean hasSufficientBalance(Money amount) {
        // 检查总资产
    }
}
// 信贷上下文 - 关注信用状况
public class Borrower {
    private String borrowerId;
    private CreditScore score;
    private Income currentIncome;
    private List<Debt> existingDebts;
    public boolean meetsLendingCriteria() {
        // 评估贷款资格
    }
}
// 风控上下文 - 关注风险指标
public class RiskProfile {
    private String profileId;
    private RiskLevel level;
    private List<RiskIndicator> indicators;
    private FraudScore fraudScore;
    public boolean requiresAdditionalVerification() {
        // 判断是否需要额外验证
    }
}

常见集成模式(Context Mapping)

限界上下文之间的集成有几种模式:

1 防腐层模式(Anti-Corruption Layer)

// 上下文之间的集成示例
public class ExternalOrderAdapter {
    private final ExternalSystemClient client;
    // 将外部系统的订单转换为本系统的模型
    public SalesOrder convertToSalesOrder(ExternalOrder externalOrder) {
        return SalesOrder.builder()
            .orderId(externalOrder.getOrderNumber())
            .items(convertItems(externalOrder.getProducts()))
            .totalAmount(convertMoney(externalOrder.getTotalPrice()))
            .customer(convertCustomer(externalOrder.getBuyerInfo()))
            .build();
    }
    // 保护本系统不受外部模型变化影响
    public void syncFromExternal() {
        List<ExternalOrder> externalOrders = client.fetchNewOrders();
        externalOrders.forEach(order -> {
            SalesOrder salesOrder = convertToSalesOrder(order);
            salesOrderRepository.save(salesOrder);
        });
    }
}

2 共享内核模式(Shared Kernel)

// 共享的通用概念
public class Money {
    private final BigDecimal amount;
    private final Currency currency;
    // 所有上下文共享的不可变对象
    public Money add(Money other) {
        validateCurrency(other);
        return new Money(this.amount.add(other.amount), this.currency);
    }
}

实际落地建议

1 识别限界上下文的方法

  1. 看组织结构:业务部门划分往往是天然边界
  2. 看业务术语:同一术语如有不同解释,就是不同上下文
  3. 看数据一致性:对数据一致性要求不同
  4. 看业务逻辑:同一实体有不同生命周期

2 上下文规模建议

❌ 不推荐:非常小的上下文
服务A: 订单创建
服务B: 订单删除
服务C: 订单查询
✅ 推荐:业务领域聚合
服务A: 销售上下文(订单创建、修改、查询)
服务B: 库存上下文(库存管理、调拨)
服务C: 支付上下文(支付、退款)

3 实践要点

实施限界上下文的经验规则:
  1. 每个上下文是一个微服务的候选
  2. 上下文内的概念必须自洽
  3. 上下文之间通过领域事件或API集成
  4. 不要跨上下文共享数据库
  5. 上下文内的通用语言要统一

限界上下文的价值

  • 👍 明确业务边界,降低复杂性
  • 👍 每个领域模型更清晰、易维护
  • 👍 促进团队间的职责划分
  • 👍 为微服务拆分提供理论依据

核心要诀

“不要试图用一个大而全的模型解决所有问题,而是把大领域拆分为多个小上下文,各自管好自己的一亩三分地。”

如果你有具体的业务场景想要分析,欢迎提供详细信息,我可以帮你分析应该如何划分限界上下文。

抱歉,评论功能暂时关闭!