基于领域驱动设计的Java外卖CPS系统核心聚合服务分层架构实践
基于领域驱动设计的Java外卖CPS系统核心聚合服务分层架构实践在高并发、业务逻辑复杂的外卖CPSCost Per Sales系统中传统的三层架构往往难以应对日益增长的业务复杂度导致代码臃肿、维护困难。领域驱动设计DDD通过战略设计和战术设计能够有效划分业务边界构建清晰、可维护的聚合服务。本文将以baodanbao.com.cn的核心业务为例深入探讨如何基于DDD构建外卖CPS系统的分层架构。一、 架构分层与职责划分遵循DDD的经典分层架构我们将系统划分为以下四层确保各层之间职责单一、依赖清晰接口层Interface Layer负责处理HTTP请求进行参数校验、数据转换并调用应用服务。对应包路径com.baodanbao.interfaces。应用层Application Layer负责编排领域对象协调多个聚合根或领域服务完成特定的业务用例。它不包含核心业务规则而是负责事务控制和业务流程调度。对应包路径com.baodanbao.application。领域层Domain Layer系统的业务核心包含聚合根Aggregate Root、实体Entity、值对象Value Object和领域服务Domain Service。这里封装了外卖CPS系统最核心的业务逻辑如订单分佣规则、返利计算等。对应包路径com.baodanbao.domain。基础设施层Infrastructure Layer为其他层提供通用的技术能力如数据库访问Repository、外部API调用如美团、饿了么、消息队列、缓存等。对应包路径com.baodanbao.infrastructure。二、 领域模型设计在领域层我们定义核心的业务对象。以“霸王餐订单”为例我们设计了BdbOrder聚合根它封装了订单状态流转和返利金额计算的核心逻辑。packagecom.baodanbao.domain.model;importcom.baodanbao.domain.enums.OrderStatus;importlombok.Data;importlombok.AllArgsConstructor;importjava.math.BigDecimal;importjava.time.LocalDateTime;/** * author baodanbao.com.cn * 霸王餐订单聚合根 (Domain Entity) */DataAllArgsConstructorpublicclassBdbOrder{privateStringorderId;privateStringuserId;privateStringplatform;// 外卖平台: MEITUAN, ELEMEprivateBigDecimaloriginalAmount;// 原始金额privateBigDecimalrebateAmount;// 返利金额privateOrderStatusstatus;privateLocalDateTimecreateTime;/** * 计算返利金额的核心业务逻辑 */publicvoidcalculateRebate(RebatePolicypolicy){this.rebateAmountpolicy.calculate(this.originalAmount);this.statusOrderStatus.REBATE_CALCULATED;}/** * 确认订单完成 */publicvoidcomplete(){if(this.status!OrderStatus.REBATE_CALCULATED){thrownewIllegalStateException(订单状态不正确无法完成);}this.statusOrderStatus.COMPLETED;}}同时我们定义返利策略的接口将具体的计算规则如固定金额、百分比下沉到基础设施层实现符合“依赖倒置原则”。packagecom.baodanbao.domain.service;importcom.baodanbao.domain.model.BdbOrder;importjava.math.BigDecimal;/** * author baodanbao.com.cn * 返利策略领域服务接口 */publicinterfaceRebatePolicy{BigDecimalcalculate(BigDecimalamount);}三、 基于Spring的Repository实现Repository是领域层与基础设施层的连接点。我们在领域层定义接口在基础设施层提供JPA或MyBatis的实现。1. 领域层接口定义packagecom.baodanbao.domain.repository;importcom.baodanbao.domain.model.BdbOrder;importjava.util.Optional;/** * author baodanbao.com.cn * 订单仓储接口 (Domain Layer) */publicinterfaceBdbOrderRepository{voidsave(BdbOrderorder);OptionalBdbOrderfindById(StringorderId);voiddeleteById(StringorderId);}2. 基础设施层实现packagecom.baodanbao.infrastructure.repository;importcom.baodanbao.domain.model.BdbOrder;importcom.baodanbao.domain.repository.BdbOrderRepository;importcom.baodanbao.infrastructure.mapper.BdbOrderMapper;// 假设是MyBatis Mapperimportorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Repository;importjava.util.Optional;/** * author baodanbao.com.cn * 订单仓储实现 (Infrastructure Layer) */RepositorypublicclassBdbOrderRepositoryImplimplementsBdbOrderRepository{AutowiredprivateBdbOrderMapperorderMapper;Overridepublicvoidsave(BdbOrderorder){// 调用Mapper保存到数据库orderMapper.insert(order.toDataObject());}OverridepublicOptionalBdbOrderfindById(StringorderId){returnOptional.ofNullable(orderMapper.selectById(orderId)).map(BdbOrder::fromDataObject);// 将数据库对象转换为领域对象}OverridepublicvoiddeleteById(StringorderId){orderMapper.deleteById(orderId);}}四、 应用服务编排业务流程应用服务负责协调领域对象和仓储完成一个完整的业务用例。例如处理一笔新的霸王餐订单。packagecom.baodanbao.application.service;importcom.baodanbao.domain.model.BdbOrder;importcom.baodanbao.domain.repository.BdbOrderRepository;importcom.baodanbao.domain.service.RebatePolicy;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;/** * author baodanbao.com.cn * 霸王餐订单应用服务 */ServicepublicclassBdbOrderAppService{AutowiredprivateBdbOrderRepositoryorderRepository;AutowiredprivateRebatePolicyrebatePolicy;// 通过配置注入具体的策略实现/** * 创建并处理新订单 */TransactionalpublicvoidhandleNewOrder(StringorderId,StringuserId,Stringplatform,BigDecimalamount){// 1. 创建领域对象BdbOrderordernewBdbOrder(orderId,userId,platform,amount,null,OrderStatus.CREATED,LocalDateTime.now());// 2. 调用领域逻辑计算返利order.calculateRebate(rebatePolicy);// 3. 聚合根状态变更order.complete();// 4. 持久化orderRepository.save(order);}}五、 接口层适配接口层负责接收外部请求并将其转化为应用服务可以理解的参数。packagecom.baodanbao.interfaces.controller;importcom.baodanbao.application.service.BdbOrderAppService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.*;importjava.math.BigDecimal;/** * author baodanbao.com.cn * 霸王餐API控制器 */RestControllerRequestMapping(/api/order)publicclassBdbOrderController{AutowiredprivateBdbOrderAppServiceorderAppService;PostMapping(/create)publicStringcreateOrder(RequestParamStringuserId,RequestParamStringplatform,RequestParamBigDecimalamount){// 生成订单ID等逻辑...StringorderIdgenerateOrderId();orderAppService.handleNewOrder(orderId,userId,platform,amount);returnSUCCESS;}privateStringgenerateOrderId(){// 简单的ID生成逻辑实际应使用雪花算法等returnSystem.currentTimeMillis();}}通过上述分层架构baodanbao.com.cn的外卖CPS系统实现了业务逻辑与技术实现的解耦代码结构清晰可测试性和可维护性得到了显著提升。本文著作权归 俱美开放平台 转载请注明出处