很多开发落地 DDD 时踩两大坑一是Repository接口与实现分层乱放领域代码耦合数据库技术二是分不清ApplicationService应用服务、DomainService领域服务职责边界。本文结合工业最优架构规范 生活化案例一站式讲清 DDD 四层架构规范与服务分层准则可直接落地项目。一、DDD 标准四层架构Repository 接口在 Domain、实现落在 Infra主流 DDD 标准划分为Interface 接口层、Application 应用层、Domain 领域层、Infra 基础设施层仓储 Repository 遵循接口归领域、实现归基础设施核心规范也是依赖倒置原则的经典落地。1. 各分层职责与核心组件分层核心职责包含组件Interface 接口层输入输出控制请求接入参数基础校验长度非空格式枚举结果封装异常处理Controller、DTO、VO、全局异常处理器Application 应用层流程细节业务流程编排事务管控协调仓储与外部资源应用 Service只做流程不实现业务规则几乎不写if判断Domain 领域层业务细节承载业务规则校验核心业务规则领域模型技术无关与底层技术解耦聚合根、Repository 接口、DomainService、领域枚举Infra 基础设施层技术细节数据库缓存RPCMQRepository 实现类、Mybatis Mapper、Redis 工具、RPC 客户端动作放在哪一层示例核心业务规则Domain 领域层计算价格、库存校验多聚合根操作Domain 领域层领域服务多聚合根操作流程编排、事务Application 应用层下单流程、事务控制RPC 调用Infra 基础设施层Dubbo、Feign、HTTP发送 MQInfra 基础设施层RocketMQ、Kafka数据库操作Infra 基础设施层MyBatis、JPA缓存操作Infra 基础设施层Redis调用流向前端→Interface→Application(组装Repository和Domain→Domain (Repository 接口)←Infra (Repository 实现)四、代码示例订单调用用户服务1. 定义接口放在 Domain / Anti-Corruption 防腐层这一层只定义 “要什么”不写实现。// 防腐层/领域层接口public interface UserService { UserDTO getUser(Long userId);}2. Application 应用层调用接口完全不知道底下是 RPC / 本地 / 假数据Service public class OrderApplicationService { // 注入接口 private final UserService userService; public Order createOrder(Long userId, ...) { // 调用完全无感 UserDTO user userService.getUser(userId); // ... }}3. Infra 层实现 RPC真正写 Dubbo/Feign这才是写 RPC 代码的地方// Infra 层 Repository public class UserServiceRpcImpl implements UserService { // RPC 客户端 private final UserRpcClient userRpcClient; Override public UserDTO getUser(Long userId) { // 真正 RPC 调用 return userRpcClient.getUserById(userId); }}2. Repository 分层细节说明类所属分层核心作用技术依赖Order 聚合根Domain封装订单业务属性与行为、业务规则无任何 DB/MyBatis 依赖OrderRepository接口Domain定义聚合根存取契约仅依赖聚合根不绑定存储技术OrderRepositoryImpl实现Infra基于 MySQL/MyBatis 完成数据存取依赖 Repository 接口 Mapper 数据库组件OrderMapperInfra直接和数据库交互依赖 Mybatis、JDBC代码示例仓储实现javaRepositorypublic class OrderRepositoryImpl implements OrderRepository {Overridepublic Order findById(Long orderId){//查询订单主表Order order orderMapper.selectById(orderId);//查询订单项子数据ListOrderItem items orderItemMapper.selectList(Wrappers.lambdaQuery(OrderItem.class).eq(OrderItem::getOrderId,orderId));//组装聚合根order.setOrderItems(items);return order;}}3. 该分层方案优缺点优势符合依赖倒置 DIP切换存储MySQL→Redis/ES仅修改 Infra 实现领域、应用层代码无需改动领域纯净解耦聚合根无任何技术框架依赖只聚焦业务逻辑单元测试便捷测试应用 / 领域代码时 Mock 仓储接口即可不用启动数据库技术收敛所有 ORM、缓存、RPC 等技术代码统一收敛在 Infra业务代码无技术污染架构易迭代分库分表、更换 ORM、多数据源改造全部局限在基础设施层。缺点项目分包层级变多小型 CRUD 项目略显冗余极简小项目可折中仓储实现和接口同包放入 Domain省略独立 Infra 目录。4. 架构选型对比传统三层架构Controller→Service→MapperDDD 项目不推荐Repository 接口实现全部放在业务包领域逻辑与数据库代码混杂换存储需大面积修改业务代码难以做单元测试。极简 DDD小型单体项目首选Repository 接口仍在 Domain实现类和 Mapper 统一放在 Domain 包省去 Infra 分层保留 DDD 核心思想降低开发成本。5. 可选扩展分层大型中台 / 复杂微服务普通业务四层架构即可大型交易系统可额外新增三层Common 公共层全局工具类、统一返回体、错误码Client SDK 层RPC 对外调用接口与 DTO单独打包供第三方依赖Query 视图层CQRS 读写分离复杂报表、多表查询单独拆分查询仓储。五、一分钟分清 ApplicationService 与 DomainService附生活化 业务案例核心口诀应用服务管流程编排与外部资源领域服务管核心业务规则应用层调用领域层领域永远不反向依赖应用。案例 1银行转账场景需求A 账户转账 100 元至 B 账户扣款、加钱、记录流水、发送通知。1. DomainService领域服务只处理核心业务规则只负责资金增减、余额校验等不可变更的业务逻辑无事务、不查库、不发消息、不调用第三方仅修改聚合根状态。javapublic class TransferDomainService {//纯核心业务规则余额校验资金划转public void transfer(Account from, Account to, BigDecimal money) {//领域规则余额不足抛异常if (from.getBalance().compareTo(money) 0) {throw new BalanceNotEnoughException();}from.deduct(money); //扣款to.credit(money); //入账}}2. ApplicationService应用服务流程编排总指挥负责查询聚合、开启事务、调用领域逻辑、持久化数据、发送短信 / 消息等外围操作不编写业务规则。javaServiceTransactional //事务定义在应用层public class TransferApplicationService {private final TransferDomainService transferDomainService;private final AccountRepository accountRepository;private final NotifyService notifyService;public void transfer(Long fromId, Long toId, BigDecimal money) {//1. 仓储查询获取聚合Account from accountRepository.findById(fromId);Account to accountRepository.findById(toId);//2. 调用领域服务执行核心规则transferDomainService.transfer(from, to, money);//3. 持久化变更数据accountRepository.save(from);accountRepository.save(to);}}形象比喻DomainService 银行法定转账规则ApplicationService 大堂经理统筹全流程。案例 2订单创建扣库存实战落地DomainService领域层跨聚合业务规则javapublic class OrderCreateDomainService {public Order createOrder(Long userId, ListItem items) {Stock stock stockRepository.findById(...);Order order new Order();stock.lockStock(items); //领域规则锁定库存order.calculateTotalPrice(items); //领域规则计算订单总价return order;}}ApplicationService应用层流程编排javaServiceTransactionalpublic class OrderApplicationService {public OrderVO createOrder(Long userId, ListItem items) {//调用领域生成订单Order order orderCreateDomainService.createOrder(userId, items);//落地库orderRepository.save(order);//发送MQ消息mqService.sendOrderCreatedMsg(order.getId());//DTO转换返回return converter.toVO(order);}}区分总结 3 条铁律跨聚合根操作、核心业务校验、业务计算逻辑 → DomainService事务控制、DB 存取、MQ/RPC/ 短信调用、参数组装、VO 转换 → ApplicationService依赖顺序Controller→ApplicationService→DomainService→聚合根单向依赖。六、落地总结中大型项目严格遵循四层架构Repository 接口 Domain、实现 Infra业务规则落 DomainService流程编排落 ApplicationService小型 CRUD 项目简化架构去掉独立 Infra 分层仓储实现和接口同包保留领域与应用服务分层思想即可DDD 落地核心不变技术细节下沉基础设施业务规则收敛领域层彻底实现业务与技术解耦。