DDD的简单落地实现

目录

概述

和微服务的联系

具体划分

遵循依赖倒置原则

其他规范

具体实现代码

总结


概述

领域式驱动(DDD)

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

和微服务的联系

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

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

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

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

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

具体划分

具体的目录划分如下

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

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

interfaces->controller

application(新增)

service->domain

infrastructure->dao

map
    ┣ interfaces
    ┃ ┣ assembler
    ┃ ┃            
    ┃ ┣ controller                 #接口层,主要有接口和实现类型的相关转换(assembler)
    ┃ ┃ ┣ v1
    ┃ ┣ dto
    ┃ ┃ 
    ┣ application
    ┃ ┣ service                    #应用层主要用于组装各个领域实现业务,不参与具体业务的实现                                                        
    ┃ ┃ ┣ ...
    ┃ ┃ ┣ impl
    ┣ domain
    ┃ ┣ entity
    ┃ ┃ ┣ entity1                   #实体
    ┃ ┃ ┣ ...
    ┃ ┣ vo
    ┃ ┃ ┣                           #映射项值校验vo
    ┃ ┣ service
    ┃ ┃ ┣ service1                  #映射领域服务
    ┃ ┃ ┣ impl
    ┃ ┃ ┃ ┣ Impl1                   #映射领域服务实现
    ┃ ┃ ┃ ┣ ...
    ┃ ┣ repository
    ┃ ┃ ┣ ...
    ┣ infrastructure                #数据库交互,或各种工具类的视线层
    ┃ ┣ constant
    ┃ ┃ ┣ RedisKeyConstants
    ┃ ┣ mapper
    ┃ ┃ ┣ MappingHeaderMapper
    ┃ ┣ util
    ┃ ┃ ┣ util                       #工具类
resource
    ┣ mapper
    ┃ ┣ MappingValueRelationMapper.xml
    ┃ ┣ ...

遵循依赖倒置原则

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

其他规范

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

2.遵循单一职责。

具体实现代码

interfaces->controller

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

    /**
     * 新增标签
     * */
    @PostMapping(value = "/addIconTag")
    public IconTag addIconTag(@RequestBody IconTag iconTag){
        return baseIconService.addIconTag(iconTag);
    }

application->serviceimpl

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

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

    @Override
    public IconTag addIconTag(IconTag iconTag) {
        if (StringUtils.isBlank(iconTag.getIconTagName())){
            throw new IconFontException(IconFontErrorCode.NAME_EMPTY);
        }
        iconTag.setIconTagName(StringUtils.deleteWhitespace(iconTag.getIconTagName()));
        iconTag = iconTypeService.addIconType(iconTag);
        return iconTagService.addIconTag(iconTag);
    }

domian ->serviceimpl

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

 @Override
    public IconTag addIconTag(IconTag iconTag) {
       
        return iconTagDao.insert(iconTag);
    }

infrastructure->repository

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

        QueryWrapper<IconTag> queryWrapper = new QueryWrapper();
        queryWrapper.eq(IconCode.ICON_TAG_NAME,iconTag.getIconTagName());
        if(ObjectUtils.isNotEmpty(iconTagDao.selectList(queryWrapper))){
            throw new IconFontException(IconFontErrorCode.DUPLICATED_NAME);
        }
        handleDefaultData(iconTag);

        iconTagDao.insert(iconTag);
        return iconTagDao.selectById(iconTag.getId());

总结

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ybbgrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值