开发者社区> 超努力的写代码> 正文

阿里高级技术专家谈开源DDD框架:COLA4.1,分离架构和组件(下)

简介: 阿里高级技术专家谈开源DDD框架:COLA4.1,分离架构和组件(下)
+关注继续查看

包结构


分层是属于大粒度的职责划分,太粗,我们有必要往下再down一层,细化到包结构的粒度,才能更好的指导我们的工作。


还是拿一堆玩具举例子,分层类似于拿来了一个架子,分包类似于在每一层架子上又放置了多个收纳盒。所谓的内聚,就是把功能类似的玩具放在一个盒子里,这样可以让应用结构清晰,极大的降低系统的认知成本和维护成本


image.png


那么,对于一个后端应用来说,应该需要哪些收纳盒呢?这一块的设计真可谓是费了老鼻子劲了,基本上每一次COLA的迭代都会涉及到包结构的调整,迭代到现在,才算基本稳定下来。


image.png


各个包结构的简要功能描述,如下表所示:

层次

包名

功能

必选

Adapter层

web

处理页面请求的Controller

Adapter层

wireless

处理无线端的适配

Adapter层

wap

处理wap端的适配





App层

executor

处理request,包括command和query

App层

consumer

处理外部message

App层

scheduler

处理定时任务





Domain层

model

领域模型

Domain层

ability

领域能力,包括DomainService

Domain层

gateway

领域网关,解耦利器





Infra层

gatewayimpl

网关实现

Infra层

mapper

ibatis数据库映射

Infra层

config

配置信息





Client SDK

api

服务对外透出的API

Client SDK

dto

服务对外的DTO






你可能会有疑问,为什么Domain的model是可选的?因为COLA是应用架构,不是DDD架构。在工作中,很多同学问我领域模型要怎么设计,我的回答通常是:无有必要勿增实体。领域模型对设计能力要求很高,没把握用好,一个错误的抽象还不如不抽象,宁可不要用,也不要滥用,不要为了DDD而DDD。


问题的关键是要看,新增的模型没有给你带来收益。比如有没有帮助系统解耦,有没有提升业务语义表达能力的提升,有没有提升系统的可维护性和可测性等等。


模型虽然可选,但DDD的思想是一定要去学习和贯彻的,特别是统一语言、边界上下文、防腐层的思想,值得深入学习,仔细体会。实际上,COLA里面的很多设计思想都来自于DDD。其中就包括领域包的设计


前面的包定义,都是功能维度的定义。为了兼顾领域维度的内聚性,我们有必要对包结构进行一下微调,即顶层包结构应该是按照领域划分,让领域内聚。


也就是说,我们要综合考虑功能和领域两个维度包结构定义。按照领域和功能两个维度分包策略,最后呈现出来的,是如下图所示的顶层包节点是领域名称,领域之下,再按功能划分包结构。


image.png


例如,在我们刚刚上线的一个云店铺(cloudstore)项目中,按照COLA的分包策略,我们在每一个module下面首先按照领域做一个顶层划分,然后在领域内,再按照功能进行分包。


image.png


解耦


“高内聚,低耦合”这句话,你工作的越久,就越会觉得其有道理。


所谓耦合就是联系的紧密程度,只要有依赖就会有耦合,不管是进程内的依赖,还是跨进程的RPC依赖,都会产生耦合。依赖不可消除,同样,耦合也不可避免。我们所能做的不是消除耦合,而是把耦合降低到可以接受的程度。在软件设计中,有大量的设计模式,设计原则都是为了解耦这一目的。


在DDD中有一个很棒的解耦设计思想——防腐层(Anti-Corruption),简单说,就是应用不要直接依赖外域的信息,要把外域的信息转换成自己领域上下文(Context)的实体再去使用,从而实现本域和外部依赖的解耦。


在COLA中,我们把AC这个概念进行了泛化,将数据库、搜索引擎等数据存储都列为外部依赖的范畴。利用依赖倒置,统一使用gateway来实现业务领域和外部依赖的解耦


其实现方式如下图所示,主要是在Domain层定义Gateway接口,然后在Infrastructure提供Gateway接口的实现。


image.png


举个例子,假如有一个电商系统,对于下单这个操作,它需要联动订单服务、商品服务、库存服务、营销服务等多个系统才能完成。


那么在订单域,该如何获取商品和库存信息呢?最直接的方式,无外乎就是RPC调用商品和库存服务,拿到DTO直接使用就完了。


然而,商品域吐出的是一个大而全的DTO(可能包含几十个字段),而在下单这个阶段,订单所需要的可能只是其中几个字段而已。更合适的做法,应该是在订单域中,使用gateway对商品域和库存域的依赖进行解耦。


image.png


这样做有两个好处,一个是降低了对外域信息依赖的耦合;另一个是通过上下文映射(Context mapping),确保本领域边界上下文(Bounded context)下领域知识的完整性,实现了统一语言(Ubiquitous language)。


COLA Archetype

以上就是COLA架构的核心内容了。然而这么多module,这么多package,如果要手动去创建的话,是非常繁琐和费时的。为了能够快速创建满足COLA架构的应用,我创建了两个Maven Archetype。

1.        一个是用来创建纯后端服务的archetype:cola-archetype-service。

2.        一个是用来创建adapter和后端服务一体的web应用archetype:cola-archetype-web。

另外,你也可以使用阿里云的应用生成器去生成一个COLA应用,只是那边的版本没有同步更新,可能会老旧一点。


COLA组件

使用过老版本COLA的同学,应该知道,COLA除了架构之外,还提供了一些框架级别的功能,比如拦截器功能,扩展点功能等。

之前,这种框架功能和架构混淆在一起,会让人以为使用COLA,就必须要使用这些功能。实际上二者是可以分开使用的,也就是说,你可以单纯的使用COLA架构,而不使用任何COLA组件提供的功能也是完全没问题的

当然,我还是强烈推荐你可以有选择的使用这些COLA组件,毕竟这些组件都是我们在实际工作中的总结沉淀,其复用性和价值是被反复验证过的。

为了方便管理,以及更清晰的把架构和框架区分开来。在此次COLA 4.0的升级中,我把这些功能组件全部收拢到了cola-components下面。到目前为止,我们已经沉淀了以下组件:

组件名称

功能

版本

依赖

cola-component-dto

定义了DTO格式,包括分页

1.0.0

cola-component-exception

定义了异常格式,主要有BizException和SysException

1.0.0

cola-component-statemachine

状态机组件

1.0.0

cola-component-domain-starter

Spring托管的领域实体组件

1.0.0

cola-component-catchlog-starter

异常处理和日志组件

1.0.0

exception,dto组件

cola-component-extension-starter

扩展点组件

1.0.0

cola-component-test-container

测试容器组件

1.0.0

这些组件是一个良好的开端,我相信,在未来会有更多有用的组件加入。当然,作为一个开源项目,如果你有好的组件idea,欢迎你随时为这个组件库添砖加瓦。


COLA 4.0

总结一下,在本次COLA升级中,我们进一步明确了架构和框架功能的定义。升级之后,如下图所示,COLA会被分成COLA架构和COLA组件两个部分:

1.        COLA架构:关注应用架构的定义和构建,提升应用质量。

2.        COLA组件:提供应用开发所需要的可复用组件,提升研发效率。



image.png


image.png

COLA 开源地址: https://github.com/alibaba/COLA

你可以按照以下步骤去使用COLA:

** 第一步:安装 cola archetype ** 下载cola-archetypes下的源码到本地,然后本地运行mvn install安装。

** 第二步:安装 cola components ** 下载cola-components下的源码到本地,然后本地运行mvn install安装。

** 第三步:创建应用 ** 执行以下命令:

mvn archetype:generate  -DgroupId=com.alibaba.demo -DartifactId=demoWeb -Dversion=1.0.0-SNAPSHOT -Dpackage=com.alibaba.demo -DarchetypeArtifactId=cola-framework-archetype-web -DarchetypeGroupId=com.alibaba.cola -DarchetypeVersion=4.0.0

命令执行成功的话,会看到如下的应用代码结构:


image.png


** 第四步:运行应用 ** 首先在demoWeb目录下运行mvn install(如果不想运行测试,可以加上-DskipTests参数)。然后进入start目录,执行mvn spring-boot:run。运行成功的话,可以看到SpringBoot启动成功的界面。

生成的应用中,已经实现了一个简单的Rest请求,可以在浏览器中输入 http://localhost:8080/helloworld 进行测试。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里高级技术专家谈开源DDD框架:COLA4.1,分离架构和组件(下)
阿里高级技术专家谈开源DDD框架:COLA4.1,分离架构和组件(下)
843 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
7641 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
18239 0
08.LoT.UI 前后台通用框架分解系列之——多样的Tag选择器
LOT.UI分解系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui LoT.UI开源地址如下:https://github.com/dunitian/LoTCodeBase/tree/master/LoTUI 这个必须说下,本来是用Bootstrap-Select做的,很漂亮,正好后台也是Bootstrap。
827 0
SSIS高级转换任务—模糊分组
   在模糊查找中我们提到脏数据是怎样进入到表中的事情,主要还是由于一些“Lazy-add”造成的。这种情况我们的肉眼很容易被欺骗,看上去是同一个单词,其实就差那么一个字母,变成了两个不同的单词。一个简单的例子是X-Ray Tech和xRey,我们很有可能认为他们是同一个职务,CT操作员,但是如果让计算机来处理的话,它们是两种截然不同的东西。
575 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
23610 0
Python全栈 Web(Flask框架、CRUD、聚合分组)
Flask、Python、Django、框架、服务器、客户端、浏览器、交互、WEB、Python前端、CSS、JAVA、HTML、H5、PHP、JavaScript、JQuery、分布式开发
5589 0
MapReduce框架排序和分组
前言:         Mapreduce框架就是map->reduce,其中Map中的是偏移量和行值,在其之前会使用job.setInputFormatClass定义的InputFormat将输入的数据集分割成小数据块splites,同时InputFormat提供一个RecordReder的实现。
620 0
1946
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载