美文网首页
关于DDD的总结思考

关于DDD的总结思考

作者: LHZ_123 | 来源:发表于2023-09-26 16:17 被阅读0次

    建模方法

    1. 用例分析法
    2. 事件风暴法
    • 第一步,识别出领域事件和业务规则


      截屏2023-09-27 11.21.07.png
    • 第二步,识别命令和执行者


      截屏2023-09-27 11.25.40.png
    • 第三步,识别领域名词


      截屏2023-09-27 11.29.40.png

    建立领域模型

    主要是要识别领域对象(domain object),领域对象之间的关系,以及领域对象的关键属性,必要的时候还要将领域对象组织成模块。

    找到领域实体,描述实体规则,画出实体之间的关系

    截屏2023-09-27 14.03.02.png

    划分模块

    很多实体和关联混杂在一起,形成了一个“蜘蛛网”。但人的认知能力是有限的,面对这样一张复杂的对象网络,就产生了认知过载(cognitive overload)。解决这一问题的方法就是“模块化”。也就是说,把模型中的业务概念组织成若干高内聚的模块(module),而模块之间尽量低耦合。

    截屏2023-09-27 14.02.47.png

    按领域模型设计数据库

    截屏2023-09-27 14.44.59.png

    分层架构设计

    DDD分层架构.drawio.png

    代码设计

    推荐的分包原则

    截屏2023-09-27 15.48.27.png

    结构化分解

    对于复杂的业务流程,可以使用结构化分解让代码有层次更清晰。


    截屏2023-09-27 15.52.28.png 截屏2023-09-27 15.52.42.png 截屏2023-09-27 15.53.05.png

    “表意接口”(Intention-Revealing Interfaces)模式

    • 每个类和方法的命名都应该尽量直观地反映领域知识,与统一语言保持一致。这种做法也是 DDD 的一个模式,叫做 “Intention-Revealing Interfaces”,可以译作表意接口。
    • 将领域知识(规则)内聚到领域实体或领域服务中,避免分散在各处的业务代码中,造成领域知识被割裂肢解和代码的业务语义表现弱。


      截屏2023-09-27 15.57.29.png
    截屏2023-09-27 15.57.38.png

    “领域服务”(Domain Service)模式

    • 领域的规则校验器xxxValidator,也叫领域服务
    package chapter11.unjuanable.application.orgmng;
    // imports...
    
    @Service
    public class OrgService {
        private final OrgValidator validator;  //代替了原来多个 Repository
        private final OrgRepository orgRepository;
    
        @Autowired
        public OrgService(OrgValidator validator
                  , OrgRepository orgRepository) {
            // 为依赖注入赋值...
        }
    
        public OrgDto addOrg(OrgDto request,Long userId) {
            validator.validate(request); // 代替原来的 validate() 方法调用
            Org org = buildOrg(request, userId);
            org = orgRepository.save(org);
            return buildOrgDto(org);
        }
    
        private OrgDto buildOrgDto(Org org) {
           //将领域对象转成DTO...
        }
    
        private Org buildOrg(OrgDto request, Long userId) {
           //将DTO转成领域对象...
        }
    
    • 领域依赖的处理器xxxHandler,也叫领域服务
    package chapter12.unjuanable.application.orgmng;
    // imports ...
    
    @Service
    public class OrgService {
        private final OrgBuilderFactory orgBuilderFactory;
        private final OrgRepository orgRepository;
        private final OrgHandler orgHandler;  //新增了一个领域服务依赖
    
        @Autowired
        public OrgService(OrgBuilderFactory orgBuilderFactory
                , OrgHandler orgHandler
                , OrgRepository orgRepository) {
            // 为依赖注入赋值 ...
        }
    
        @Transactional
        public OrgDto addOrg(OrgDto request,Long userId) {
            // 添加组织的功能已完成,这里省略 ...
        }
    
        //修改组织基本信息
        @Transactional
        public OrgDto updateOrgBasic(Long id, OrgDto request, Long userId) {
            Org org = orgRepository.findById(request.getTenant(), id)
                    .orElseThrow(() -> {
                        throw new BusinessException("要修改的组织(id =" 
                                    + id + "  )不存在!");
                    });
    
            orgHandler.updateBasic(org, request.getName() 
                    , request.getLeader(), userId);
                    
            orgRepository.update(org);
    
            return buildOrgDto(org);
        }
    
        //取消组织
        @Transactional
        public Long cancelOrg(Long id, Long tenant, Long userId) {
            Org org = orgRepository.findById(tenant, id)
                    .orElseThrow(() -> {
                        throw new BusinessException("要取消的组织(id =" 
                                    + id + "  )不存在!");
                    });
    
            orgHandler.cancel(org, userId);
            orgRepository.update(org);
    
            return org.getId();
        }
    
        private static OrgDto buildOrgDto(Org org) {
            // 将领域对象转换成DTO
        }
    }
    

    “工厂”(Factory)模式

    DDD 认为,领域对象的创建逻辑也是领域层的一部分。如果创建领域对象的逻辑比较简单,可以直接用对象的构造器来实现。但是如果比较复杂,就应该把创建逻辑放到一个专门的机制里,来保证领域对象的简洁和聚焦。这里说的专门机制可以是一个方法或者一个类,可以有很多种实现方式。不论具体方式是什么,在 DDD 里统称为工厂(Factory)模式。

    通常,领域对象的工厂放置在domain层,到时对象构建的入参基本上来自application层的参数。如何既保持层间依赖原则,又不新增中间对象,我们可以借助Builder模式来实现对象的构建。

    package chapter11.unjuanable.domain.orgmng;
    // import...
    
    public class OrgBuilder {
        //用到的 validator
        private final CommonValidator commonValidator;
        private final OrgTypeValidator orgTypeValidator;
        private final SuperiorValidator superiorValidator;
        private final OrgNameValidator orgNameValidator;
        private final OrgLeaderValidator orgLeaderValidator;
    
        //用这些属性保存创建对象用到的参数
        private Long tenantId;
        private Long superiorId;
        private String orgTypeCode;
        private Long leaderId;
        private String name;
        private Long createdBy;
    
        public OrgBuilder(CommonValidator commonValidator
                , OrgTypeValidator orgTypeValidator
                , SuperiorValidator superiorValidator
                , OrgNameValidator orgNameValidator
                , OrgLeaderValidator orgLeaderValidator) {
            //注入各个 Validator... 
        }
    
        // 为builder 的 tenant 属性赋值,然后返回自己,以便实现链式调用
        public OrgBuilder tenantId(Long tenantId) {
            this.tenantId = tenantId;
            return this;
        }
        // 其他5个属性赋值与 tenantId 类似 ...
        
        public Org build() {
            validate();
    
            Org org = new Org();
            org.setOrgTypeCode(this.orgTypeCode);
            org.setLeaderId(this.leaderIc);
            org.setName(this.name);
            org.setSuperiorId(this.superiorId);
            org.setTenantId(this.tenantId);
            org.setCreatedBy(this.createdBy);
            org.setCreatedAt(LocalDateTime.now());
    
            return org;
        }
    
        private void validate() {
            commonValidator.tenantShouldValid(tenantId);
            orgTypeValidator.verify(tenantId, orgTypeCode);
            superiorValidator.verify(tenantId, superiorId, orgTypeCode);
            orgLeaderValidator.verify(tenantId, leaderId);
            orgNameValidator.verify(tenantId, name, superiorId);
        }
    }
    

    本文主要参考

    钟敬老师的《手把手教你落地 DDD》
    张建飞老师的《基于DDD的应用架构设计和实践》

    相关文章

      网友评论

          本文标题:关于DDD的总结思考

          本文链接:https://www.haomeiwen.com/subject/mmqhbdtx.html