目录
概述
和微服务的联系
具体划分
遵循依赖倒置原则
其他规范
具体实现代码
总结
领域式驱动(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 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的架构模式的,当业务比较复杂的时候,迭代比较多的时候就适合这种模式,后续还有很多优化的地方,此次只是首次实现。