# ddd **Repository Path**: pingfanrenbiji/ddd ## Basic Information - **Project Name**: ddd - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2021-08-26 - **Last Updated**: 2025-08-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README * [架构风格](#架构风格) * [DEMO](#demo) * [使用方式](#使用方式) * [方式1、如果你的应用没有使用springboot](#方式1如果你的应用没有使用springboot) * [方式2、如果你的应用使用springboot](#方式2如果你的应用使用springboot) * [重要组件介绍](#重要组件介绍) * [Command(命令)](#command命令) * [Event(事件)](#event事件) * [CommandBus(命令总线)](#commandbus命令总线) * [EventBus(事件总线)](#eventbus事件总线) * [CommandHandler(命令处理器)](#commandhandler命令处理器) * [CommandInterceptor(命令拦截器)](#commandinterceptor命令拦截器) * [CommandValidator(命令验证器)](#commandvalidator命令验证器) * [Assembler(组装器)](#assembler组装器) * [Converter(转换器)](#converter转换器) * [ConcurrencyConflicts(并发校验工具)](#concurrencyconflicts并发校验工具) * [参考](#参考) ### 架构风格 结合了整洁架构风格 、CQRS风格以及分层架构风格,并采用依赖原则分4层,如下: * interface-adapter 接口适配层(适配dubbo、rest接口等协议) * application 应用层(实现用例的地方,eg:电商场景里的用户下单是个用例) * domain 领域层(写领域逻辑的地方,eg:电商场景里的用户下单包含订单逻辑、商品逻辑、以及优惠逻辑等) * infrastructure 基础层(放Cache、MQ框架、数据库持久实现等的地方) 模块依赖关系以及与整洁架构风格模块对应关系: ![采用依赖倒置的依赖关系](https://mmbiz.qpic.cn/mmbiz_png/IuUJiciaodp4ePgKtYeUV7aroO6yQUTGzwvFPFUDqKkq0GmticL51s0f11Qjx5n6SB7x1bwY8Js4YbJWnVxiaDUrSQ/0?wx_fmt=png) ### DEMO * 执行ddd-module-demo/ddd-bootstrap下的App类的main方法 * 创建一个商品 ``` curl -H "Content-Type:application/json" -X POST http://localhost:8080/product/create --data '{"name":"test","description":"test description"}' ``` 代码路径:ProductController.createProduct * 获取商品信息(点击) ``` http://localhost:8080/product/get?productId=1 ``` 代码路径:ProductController.getProduct * 获取商品信息(命令行) ``` curl -H "Content-Type:application/json" -X GET 'http://localhost:8080/product/get?productId=1' ``` 代码路径:ProductController.getProduct * 分页查询商品信息(点击) 代码路径:ProductController.queryProducts * 修改商品 ``` curl -H "Content-Type:application/json" -X POST http://localhost:8080/product/update --data '{"productId":"1","name":"test","description":"test description"}' ``` 代码路径:ProductController.updateProduct * 禁用商品 ``` curl -H "Content-Type:application/json" -X POST 'http://localhost:8080/product/deactivate?productId=1' ``` 代码路径:ProductController.deactivateProduct * 启用商品 ``` curl -H "Content-Type:application/json" -X POST 'http://localhost:8080/product/activate?productId=1' ``` 代码路径:ProductController.activateProduct * 删除商品 ``` curl -H "Content-Type:application/json" -X POST 'http://localhost:8080/product/delete?productId=1' ``` 代码路径:ProductController.deleteProduct ### 使用方式 注意:需要提前将jar ```mvn clean install -Dmaven.test.skip=true```进maven本地库或私库里 * ##### 方式1、如果你的应用没有使用springboot ``` com.runssnail.ddd ddd-spring ${ddd.version} ``` 增加spring配置,加入配置后,默认自动从spring上下文收集CommandHandler和EventHandler(需要在类上增加spring注解@Service、@Component等) ``` ``` * ##### 方式2、如果你的应用使用springboot ``` com.runssnail.ddd ddd-spring-boot-starter ${ddd.version} ``` ### 重要组件介绍 * ##### Command(命令) 一个Command对象对应一个用例的请求数据 ``` @Data public class CreateProductCommand extends AbstractCommand { private String name; private String description; @Override public Class resultType() { return Result.class; } } ``` * ##### Event(事件) 表示一个领域事件,用例完成后,发布一个领域事件 ``` @Getter public class ProductCreatedEvent extends AbstractEvent { private String productId; public ProductCreatedEvent(String productId) { this.productId = productId; } } ``` * ##### CommandBus(命令总线) 分发Command到对应的CommandHandler里去处理业务 ![命令总线UML图](https://mmbiz.qpic.cn/mmbiz_png/IuUJiciaodp4cjurx93TrL8KyPFBtQaXcm2DOIicqKiau4rqysAmFM5S90mPXctum5E0hnabP7tccUM8rm1g57b30A/0?wx_fmt=png) ``` @Component public class ProductApplicationService { @Autowired private CommandBus commandBus; /** * 创建商品 * * @param command * @return */ @Transactional public Result createProduct(CreateProductCommand command) { return commandBus.dispatch(command); } } ``` * ##### EventBus(事件总线) 用来发布领域事件 ![事件总线UML图](https://mmbiz.qpic.cn/mmbiz_png/IuUJiciaodp4cjurx93TrL8KyPFBtQaXcmibuWZy32IUmFic1lY34ddfAqpRbfvlD7rp7zo93Q5ExJ78YAb7u525eA/0?wx_fmt=png) ``` @Component public class CreateProductCommandHandler extends BaseCommandHandler { // 这里省略... @Autowired private EventBus eventBus; @Override public Class supportCommand() { return CreateProductCommand.class; } @Override public Result doHandle(CreateProductCommand command) { // 转换领域对象 Product product = this.productDomainService.createProduct(command); // 保存数据 productRepository.save(product); // 发布领域事件 eventBus.publish(new ProductCreatedEvent(product.getProductId())); return Result.success(product.getProductId()); } } ``` * ##### CommandHandler(命令处理器) 用来实现用例,一个Command对应一个CommandHandler ``` @Component public class CreateProductCommandHandler extends BaseCommandHandler { // 这里省略... @Override public Class supportCommand() { return CreateProductCommand.class; } @Override public Result doHandle(CreateProductCommand command) { // do bussniess return Result.success(product.getProductId()); } } ``` * ##### CommandInterceptor(命令拦截器) 用来拦截Command,支持多个CommandInterceptor处理同一个Command ``` @Component @Order(1) public class CreateProductInterceptor implements CommandInterceptor { private static final Logger log = LoggerFactory.getLogger(CreateProductInterceptor.class); @Override public Class supportCommandType() { return CreateProductCommand.class; } @Override public void beforeHandle(CreateProductCommand command) { log.info("CreateProductInterceptor.preHandle"); } @Override public void afterHandle(CreateProductCommand command, Result result) { log.info("CreateProductInterceptor.postHandle"); } } ``` * ##### CommandValidator(命令验证器) 用来验证Command参数完整性或者业务前置校验,默认支持Hibernate Validator ``` @Component public class CreateProductCommandValidator implements CommandValidator { @Override public Class supportType() { return CreateProductCommand.class; } @Override public void validate(CreateProductCommand createProductCommand) throws IllegalArgumentException, BizException { Validate.notNull(createProductCommand); Validate.notNull(createProductCommand.getName()); Validate.isTrue(createProductCommand.getName().length() <= 10); } } ``` * ##### Assembler(组装器) 用来组装查询请求数据,将领域实体对象转换成DTO后返回给外部使用,将领域对象封装在内部 ``` @Component public class CreateProductAssembler implements Assembler { @Override public ProductDTO assemble(Product product) { ProductDTO target = new ProductDTO(); BeanUtils.copyProperties(product, target); return target; } } ``` * ##### Converter(转换器) 实现领域实体对象和数据对象之间的转换 ``` @Component public class ProductConverter implements Converter { @Override public ProductDO serialize(Product product) { // todo 领域对象转换成数据对象 ProductDO productDO = new ProductDO(); productDO.setId(product.getProductId()); return productDO; } @Override public Product deserialize(ProductDO productDO) { // todo 数据对象转换成领域对象 return new Product(productDO.getId()); } } ``` * ##### ConcurrencyConflicts(并发校验工具) 用来判断修改数据时,是否产生了并发问题。 ``` @Override public void remove(Product product) throws ConcurrencyConflictException { int count = this.productDOMapper.deleteById(product.getId(), product.getOperator(), product.getConcurrencyVersion()); ConcurrencyConflicts.check(count, "remove Product, id={}, concurrencyVersion={}", product.getId(), product.getConcurrencyVersion()); } ``` ### 参考 * 整洁架构 * Alibaba COLA * AxonFramework