• DDD的简单落地实现


    目录

    概述

    和微服务的联系

    具体划分

    遵循依赖倒置原则

    其他规范

    具体实现代码

    总结


    概述

    领域式驱动(DDD)

    这种模式的核心就是根据功能去划分领域,然后在这个领域内只做这个领域的事情。

    和微服务的联系

    和微服务有什么类似的地方,划分模块。

    例如:一个大的服务,有基础微服务,人力资源微服务等,然后在具体的微服务下面可以分,更加具体的子类。

    基础微服务需要提供,账号相关功能,团队相关功能,权限相关功能,而权限相关功能和账号相关功能可以再做细分。

    领域式驱动也是这样,根据功能领域划分,就像你是一个城市设计师,这里规划修学校,哪里修公司。

    不同的是微服务是一种架构,而领域式驱动是一种思想,这种思想的灵活性更强,基本上取决于你要怎么来划分。

    具体划分

    具体的目录划分如下

    这是按照4层架构的方式来划分的,当业务更复杂的时候,也可以划分为5层,增加环境层,环境层主要是领域的行为绑定,聚合。使用得比较多的还是4层架构。

    参考三层架构的对应关系的话,也可以简单的理解为,多了一层应用层。

    interfaces->controller

    application(新增)

    service->domain

    infrastructure->dao

    1. map
    2. ┣ interfaces
    3. ┃ ┣ assembler
    4. ┃ ┃
    5. ┃ ┣ controller #接口层,主要有接口和实现类型的相关转换(assembler)
    6. ┃ ┃ ┣ v1
    7. ┃ ┣ dto
    8. ┃ ┃
    9. ┣ application
    10. ┃ ┣ service #应用层主要用于组装各个领域实现业务,不参与具体业务的实现
    11. ┃ ┃ ┣ ...
    12. ┃ ┃ ┣ impl
    13. ┣ domain
    14. ┃ ┣ entity
    15. ┃ ┃ ┣ entity1 #实体
    16. ┃ ┃ ┣ ...
    17. ┃ ┣ vo
    18. ┃ ┃ ┣ #映射项值校验vo
    19. ┃ ┣ service
    20. ┃ ┃ ┣ service1 #映射领域服务
    21. ┃ ┃ ┣ impl
    22. ┃ ┃ ┃ ┣ Impl1 #映射领域服务实现
    23. ┃ ┃ ┃ ┣ ...
    24. ┃ ┣ repository
    25. ┃ ┃ ┣ ...
    26. ┣ infrastructure #数据库交互,或各种工具类的视线层
    27. ┃ ┣ constant
    28. ┃ ┃ ┣ RedisKeyConstants
    29. ┃ ┣ mapper
    30. ┃ ┃ ┣ MappingHeaderMapper
    31. ┃ ┣ util
    32. ┃ ┃ ┣ util #工具类
    33. resource
    34. ┣ mapper
    35. ┃ ┣ MappingValueRelationMapper.xml
    36. ┃ ┣ ...

    遵循依赖倒置原则

    • 高层模块不应该过分的依赖底层模块,两者都应该依赖抽象.
    • 抽象不应该依赖于细节,细节应该依赖于抽象.

    其他规范

    1.固有的核心功能,放入领域中,而经常变动的可能变动的放在适配器中。

    2.遵循单一职责。

    具体实现代码

    interfaces->controller

    这一层是新增标签这个接口的实现,此时还未需要用到相关的实现类转换,如果传入的实体类是iconTag而需要的实体类是iconTagRemove,就可以在assembler中写入。

    1. /**
    2. * 新增标签
    3. * */
    4. @PostMapping(value = "/addIconTag")
    5. public IconTag addIconTag(@RequestBody IconTag iconTag){
    6. return baseIconService.addIconTag(iconTag);
    7. }

    application->serviceimpl

    这里主要是应用层,负责编排各个领域。

    先到iconTag层拿到需要的iconType,在到Tag层去处理相关业务。

    1. @Override
    2. public IconTag addIconTag(IconTag iconTag) {
    3. if (StringUtils.isBlank(iconTag.getIconTagName())){
    4. throw new IconFontException(IconFontErrorCode.NAME_EMPTY);
    5. }
    6. iconTag.setIconTagName(StringUtils.deleteWhitespace(iconTag.getIconTagName()));
    7. iconTag = iconTypeService.addIconType(iconTag);
    8. return iconTagService.addIconTag(iconTag);
    9. }

    domian ->serviceimpl

    领域可以理解为编排各个数据库交互层,当业务很复杂的时候,也可以新增领域下的子域。如果这个领域需要实现的功能涉及到多个数据库层的操作,就可以。

    1. @Override
    2. public IconTag addIconTag(IconTag iconTag) {
    3. return iconTagDao.insert(iconTag);
    4. }

    infrastructure->repository

    数据库交互层,主要是用以数据库相关的操作。

    1. QueryWrapper queryWrapper = new QueryWrapper();
    2. queryWrapper.eq(IconCode.ICON_TAG_NAME,iconTag.getIconTagName());
    3. if(ObjectUtils.isNotEmpty(iconTagDao.selectList(queryWrapper))){
    4. throw new IconFontException(IconFontErrorCode.DUPLICATED_NAME);
    5. }
    6. handleDefaultData(iconTag);
    7. iconTagDao.insert(iconTag);
    8. return iconTagDao.selectById(iconTag.getId());

    总结

    DDD虽然架构层级上来说更多了,但是具体实现下来,特别是当业务越加越多的时候,就可以感觉到,比一般的三层架构的方式要清晰一些,但是还是有很多需要具体理解的方面,如什么是领域事件,其实感觉得到,业务过于简单的时候,是不太适合使用DDD的架构模式的,当业务比较复杂的时候,迭代比较多的时候就适合这种模式,后续还有很多优化的地方,此次只是首次实现。

  • 相关阅读:
    vue3问题记录(持续更新)
    Uniapp实现APP云打包
    牛客: BM7 链表中环的入口结点
    Rust之常用集合(二):字符串(String)
    【性能测试】ChaosTesting(混沌测试)&ChaosBlade(混沌实验工具)(四)-k8s容器混沌实验
    【leetocde】128. 最长连续序列
    [附源码]JAVA毕业设计货币博物馆展品管理系统(系统+LW)
    【面试题】Vue2动态添加路由 router.addRoute()
    Python入门基础篇
    vue中,js获取svg内容并填充到svg图中
  • 原文地址:https://blog.csdn.net/Y920036515/article/details/128132543