一、引言
学习 COLA 这个框架的理由比较功利——项目中用到了。虽然在后续的开发过程中已将 COLA 框架的依赖全部移除,但项目的架构以及开发依然是按照 COLA 框架,乃至其所代表的 DDD 架构的指导思想进行的。所以本篇会大致介绍 DDD 架构基本概念、COLA 框架各子项目,以及子项目文件夹的作用。
二、正文
2.1 DDD架构
领域驱动设计(Domain-Driven Design,简称DDD)是一种软件开发方法论,它强调以业务领域为中心进行软件开发。这种方法论由Eric Evans在其2004年出版的同名书籍《Domain-Driven Design: Tackling Complexity in the Heart of Software》中首次提出。
2.2 COLA框架
COLA框架是DDD设计思想的一种具体实现。COLA 是 Clean Object-Oriented and Layered Architecture的缩写,代表“整洁面向对象分层架构”。COLA分为两个部分,COLA架构和COLA组件。这里为了快速了解项目,主要从层级和各层级文件夹作用介绍。放一张官方的架构图:

必须要说明,由于时间紧迫,我们的开发人员在并未完全理解DDD设计思想的时候就开始了项目的架构与开发,所以项目并未完全符合DDD的设计理念。所以接下来每节归纳完COLA概念的同时,也会在结尾阐述我们项目中的实际情况应用,算是做个错误示范。
2.2.1 COLA层级
Adapter层(适配层):
负责接收外部请求,例如来自Web、无线端、消息队列等,并将其转换为内部系统可以处理的格式。它主要负责请求的适配和路由,相当于MVC架构中的Controller。
App层(应用层):
协调业务流程,处理请求,进行参数校验、上下文组装,并调用Domain层进行业务逻辑处理。它支持命令(Command)和查询(Query)分离,即CQRS模式。
Client模块(用户端层):
包含的代码应该是常见的服务接口Facade和DTO数据传输对象,如API、DTO、领域事件、Command和Query对象等等。
Domain层(领域层):
包含业务的核心逻辑和领域模型。它负责处理业务规则、领域对象和实体,以及它们之间的关系和行为。Domain层通常包含领域服务、领域模型、领域网关和资源库等。
Infrastructure层(基础设施层):
负责处理与技术相关的细节,例如数据库操作、缓存、消息队列、外部服务调用等。它还负责领域防腐,将外部依赖转化为内部可用的接口(例如Dubbo、Feign等的Rpc调用)。
项目中的实践:我们的依赖层级未符合DDD的设计思路,依赖层级为Adapter层(项目中为Controller层)->App层->Domain层->Infrastructure层。根据DDD的设计思想,Domain应当是最核心的,不应当依赖任何层级,只能被其他层级依赖。根据这个思想演化出两种解决方案:
- Infrastructure放在最顶层
- Domain和Infrastructure依赖倒置
COLA框架采取的方式为第二种。但根据COLA框架构建的本项目的依赖层级却未倒置,让项目在事实上退化成了MVC架构。以及项目业务逻辑集中于App层,代码已然腐烂(悲)。
2.2.2 COLA文件夹

各层级文件夹如图所示,个人认为有两个要点:
- 文件夹或者类命名可能在实践中有所不同,但只需相关人员在架构和开发之前约定好即可。这点非常重要,不然可能陷入微微的争执,如【Github】COLA 5.0 数据交互个人理解图 #557吵了10几楼,甚至这是二番战,别的isuue中已经做过一场。
文件夹一定是先业务后功能,如下图所示。这样能很大程度上避免不同开发人员理解不同导致不同层级文件夹或者类命名不一致导致的代码腐烂。想象一下在App层叫alert对象,在Domain叫warn对象,它们都一股脑放在各自的model文件夹中,业务一多就难以对其了。

项目中的实践:项目中的问题主要还是集中在App层(项目中为Service层)和Domain层,究其原因是因为架构阶段未拆分好业务。
- App层只有Client层接口的实现类,而无executor的CQRS对Domain层接口的调用以及consumer文件的对层级之间传递类的转换逻辑,且所有业务逻辑全部集中在实现类中。
- Domain层有feign文件夹,用于调用外部数据,但实际上Domain不应依赖其他,实际应当将feign文件夹以及相应的实现放在Infrastructure层。
三、总结
本文介绍了COLA架构的基本层级和各层级包含的文件夹,以及各自的功能。从我们的错误实践可以看出来:
- DDD非常依赖于架构时就对业务有一个很好的拆分,不然一步错步步错。
- 并且业务不复杂时也不推荐使用DDD架构,使用更简单易懂的MVC架构即可。DDD架构带来的层级复杂以及严重的类膨胀在一些简单业务场景下反而会比MVC花费更多的开发和维护实践