DDD - 整洁架构

DDD(领域驱动设计)的整洁架构 (Clean Architecture)是一种通过分层和依赖规则,确保领域模型(业务逻辑)与技术实现解耦的架构模式。其核心目标是让业务逻辑成为系统的核心,而技术细节(如数据库、框架、UI)成为可替换的"插件"。

整洁结构如何帮助团队专注于领域模型,减少外部变化的影响,提升软件质量。

一、核心原则

  1. 分层架构

    代码按职责分为多层(如接口层、应用层、领域层、基础设施层),确保各层职责明确。

  2. 依赖规则

    外层依赖内层,内层不感知外层。例如:领域层不依赖基础设施层,但基础设施层可以实现领域层定义的接口。

  3. 领域模型为核心

    领域层(Domain Layer)是核心,包含业务实体、规则和领域服务,与技术无关。

  4. 技术细节可替换

    数据库、框架等实现细节放在外层(如基础设施层),可随时替换而不影响业务逻辑。

二、整洁架构示意图

三、举例说明-电商订单系统

1. 接口层(Interface Layer)
  • 职责:处理外部输入(如 HTTP 请求、消息队列事件),将输入转换为领域层可理解的格式。

  • 示例

java 复制代码
// OrderController.java(接口层)
@RestController
public class OrderController {
    private final OrderService orderService;

    // 依赖注入应用层服务
    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }

    @PostMapping("/orders")
    public ResponseEntity<OrderDTO> createOrder(@RequestBody CreateOrderRequest request) {
        // 将 HTTP 请求转换为应用层命令
        CreateOrderCommand command = new CreateOrderCommand(request.getUserId(), request.getItems());
        Order order = orderService.createOrder(command);
        return ResponseEntity.ok(OrderDTO.fromDomain(order));
    }
}
2. 应用层(Application Layer)
  • 职责:协调领域对象和基础设施,实现用例流程,不包含业务规则。

  • 示例

java 复制代码
// OrderService.java(应用层)
public class OrderService {
    private final OrderRepository orderRepository;
    private final PaymentGateway paymentGateway;

    // 依赖基础设施接口(如 OrderRepository)
    public OrderService(OrderRepository orderRepository, PaymentGateway paymentGateway) {
        this.orderRepository = orderRepository;
        this.paymentGateway = paymentGateway;
    }

    public Order createOrder(CreateOrderCommand command) {
        // 调用领域层逻辑
        Order order = Order.create(command.getUserId(), command.getItems());
        
        // 协调支付等外部服务
        paymentGateway.processPayment(order.getTotalAmount());
        
        // 调用基础设施层保存订单
        orderRepository.save(order);
        return order;
    }
}
3. 领域层(Domain Layer)
  • 职责:定义业务实体、值对象、领域服务,包含核心业务规则。

  • 示例

java 复制代码
// Order.java(领域层)
public class Order {
    private OrderId id;
    private UserId userId;
    private List<OrderItem> items;
    private OrderStatus status;

    // 领域方法:创建订单的业务规则
    public static Order create(UserId userId, List<OrderItem> items) {
        if (items.isEmpty()) {
            throw new IllegalArgumentException("订单必须包含商品");
        }
        Order order = new Order();
        order.id = OrderId.generate();
        order.userId = userId;
        order.items = items;
        order.status = OrderStatus.CREATED;
        return order;
    }

    // 领域方法:订单状态流转规则
    public void markAsPaid() {
        if (this.status != OrderStatus.CREATED) {
            throw new IllegalStateException("只有已创建的订单可标记为已支付");
        }
        this.status = OrderStatus.PAID;
    }
}
4. 基础设施层(Infrastructure Layer)
  • 职责:实现技术细节(如数据库操作、第三方服务调用),依赖领域层接口。

  • 示例

java 复制代码
// JpaOrderRepository.java(基础设施层)
public class JpaOrderRepository implements OrderRepository {
    private final OrderJpaRepository jpaRepository;

    // 实现领域层定义的 OrderRepository 接口
    @Override
    public void save(Order order) {
        OrderEntity entity = OrderEntity.fromDomain(order);
        jpaRepository.save(entity);
    }
}

// PaymentGatewayImpl.java(基础设施层)
public class PaymentGatewayImpl implements PaymentGateway {
    @Override
    public void processPayment(BigDecimal amount) {
        // 调用第三方支付 API
        ThirdPartyPaymentClient.process(amount);
    }
}

四、关键优势

  1. 业务逻辑与技术解耦

    领域层不依赖具体数据库或框架,可独立测试和演进。例如,更换数据库只需修改基础设施层。

  2. 可维护性

    新增功能时,只需关注领域层的业务规则,无需修改技术实现。

  3. 清晰的依赖方向

    依赖始终向内指向领域层,避免循环依赖。

DDD 的整洁结构通过分层和依赖倒置,让业务逻辑成为系统的核心,技术实现成为可插拔的细节。这种设计尤其适合复杂业务系统,能够显著提升代码的可维护性和扩展性。

相关推荐
stark张宇7 分钟前
分布式事务最全图解(6种方案):从强一致的2PC到最终对账,彻底搞懂数据一致性
分布式·后端
鲸能云22 分钟前
【智慧能源】源储调售一体化架构与 EMS 滚动调度算法实践 —— 工商业光储收益提升 22% 的技术拆解
算法·架构·能源
会周易的程序员34 分钟前
5Draft使用说明书
服务器·c++·分布式·raft·共识
Swift社区37 分钟前
鸿蒙 App 如何设计 Memory Center?一文讲透 Agent 的长期记忆架构
华为·架构·harmonyos
富士康质检员张全蛋42 分钟前
Kafka实战 自定义分区器 几种常见的分区器
分布式·kafka
许彰午1 小时前
24-MyBatisHelper与autoCount
java·低代码·架构
小马过河R1 小时前
微信小程序自定义登录态维护:从入门到生产级落地
后端·微信小程序·小程序·架构·登录态
努力努力再努力wz1 小时前
【Redis入门系列】:从 RESP 协议到 redis-plus-plus:Redis 客户端编程与 C++ 接口设计
开发语言·数据库·c++·redis·分布式·缓存·架构
Dawson Zhu2 小时前
Kafka 在 AI Agent 系统中的应用:任务队列与事件总线的角色辨析及工程实践
人工智能·语言模型·架构·aigc·agi
不爱运动的跑者2 小时前
架构可视化不是“画图“:让 AI 产出可追溯架构图的四层工程
人工智能·架构