六、领域驱动设计(DDD)核心概念
DDD是处理复杂业务逻辑的架构方法论。
6.1 战略设计
核心概念:
限界上下文 (Bounded Context):
定义: 特定模型的应用边界
示例: 订单上下文、库存上下文、支付上下文
上下文映射 (Context Map):
定义: 不同限界上下文之间的关系
关系类型: 合作关系、共享内核、客户-供应商、防腐层
领域 (Domain):
定义: 问题域和业务逻辑
子域类型:
- 核心域: 核心竞争力
- 支撑域: 支持核心域
- 通用域: 通用功能
// 防腐层(Anti-Corruption Layer)示例
@Service
public class InventoryAntiCorruptionLayer {
private final InventoryExternalService inventoryService;
public InventoryResponse checkStock(String productId, int quantity) {
// 调用外部系统的响应
ExternalResponse externalResponse = inventoryService.query(productId);
// 转换为领域模型
InventoryResponse result = new InventoryResponse();
result.setAvailable(externalResponse.getCode() == 200 && externalResponse.getStock() >= quantity);
// 处理外部系统的异常响应
if (externalResponse.getCode() == 500) {
// 降级策略
result.setAvailable(true);
result.setFallback(true);
log.warn("Inventory service degraded, using fallback");
}
return result;
}
}
6.2 战术设计
// 实体(Entity)- 有唯一标识
public class Order implements AggregateRoot {
private OrderId id; // 值对象作为标识
private OrderStatus status;
private List<OrderItem> items;
private Address shippingAddress;
// 领域行为(不是贫血模型)
public void changeShippingAddress(Address newAddress) {
if (status != OrderStatus.PENDING) {
throw new DomainException("Cannot change address after payment");
}
this.shippingAddress = newAddress;
addDomainEvent(new AddressChangedEvent(id, newAddress));
}
}
// 值对象(Value Object)- 不可变,无标识
@Embeddable
public class Address {
private final String street;
private final String city;
private final String zipCode;
public Address(String street, String city, String zipCode) {
this.street = street;
this.city = city;
this.zipCode = zipCode;
}
@Override
public boolean equals(Object o) {
// 基于值的相等性判断
if (!(o instanceof Address)) return false;
Address other = (Address) o;
return Objects.equals(street, other.street)
&& Objects.equals(city, other.city)
&& Objects.equals(zipCode, other.zipCode);
}
@Override
public int hashCode() {
return Objects.hash(street, city, zipCode);
}
}
// 聚合根(Aggregate Root)- 领域一致性边界
public class Order implements AggregateRoot {
// 聚合内的所有操作都通过聚合根
private List<OrderItem> items;
public void addItem(Product product, int quantity) {
// 业务规则:订单金额不能超过10000
if (calculateTotal().add(product.getPrice().multiply(BigDecimal.valueOf(quantity)))
.compareTo(new BigDecimal("10000")) > 0) {
throw new DomainException("Order amount exceeds limit");
}
items.add(new OrderItem(product, quantity));
}
}
// 领域服务(Domain Service)- 跨聚合的业务逻辑
@Service
public class PricingService {
public Price calculateOrderPrice(Order order, User user) {
Price subtotal = order.calculateSubtotal();
Price discount = calculateDiscount(user, subtotal);
Price tax = calculateTax(subtotal.subtract(discount));
return subtotal.subtract(discount).add(tax);
}
private Price calculateDiscount(User user, Price amount) {
if (user.isVip()) {
return amount.multiply(0.1); // 10% discount
}
return Price.ZERO;
}
}
// 领域事件(Domain Event)
public class OrderShippedEvent {
private final OrderId orderId;
private final TrackingNumber trackingNumber;
private final LocalDateTime shippedAt;
}
// 仓库(Repository)- 聚合的持久化
public interface OrderRepository {
Order findById(OrderId id);
void save(Order order);
void delete(Order order);
}
七、架构师的思考框架
7.1 架构决策矩阵
7.2 架构演进:从单体到微服务
演进路径:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 单体架构 │ -> │ 垂直拆分 │ -> │ 微服务架构 │ -> │ 服务网格 │
│ Monolith │ │ 分层服务 │ │ Microservices│ │ Service Mesh│
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
2-3年 3-5年 5-10年 1-3年
何时拆分微服务?
✓ 团队规模超过20人
✓ 不同模块变更频率差异大
✓ 需要独立扩展特定功能
✓ 技术栈异构需求
✗ 业务逻辑简单,团队规模小
✗ 对延迟极其敏感
✗ 事务一致性要求极高
7.3 架构评审清单
架构评审问题清单:
非功能性需求:
- 系统预期的QPS/TPC是多少?
- 高峰流量是平时的多少倍?
- 允许的最大响应时间是多少?
- 可接受的宕机时间(SLA)是多少?
- 数据保留周期是多久?
技术选型:
- 为什么选择这个技术栈?
- 有没有考虑过替代方案?
- 技术栈的社区活跃度如何?
- 团队的熟悉程度如何?
- 是否有成熟的监控和运维工具?
安全性:
- 数据传输是否加密?
- 敏感数据如何存储?
- 防SQL注入、XSS、CSRF措施?
- API限流和防刷机制?
- 权限控制粒度?
可扩展性:
- 哪些模块需要水平扩展?
- 数据库瓶颈如何解决?
- 缓存策略是什么?
- 消息队列处理削峰填谷?
容错性:
- 单点故障如何处理?
- 降级和熔断策略?
- 数据备份和恢复方案?
- 有没有回滚计划?