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

2021-01-03 08:33

前几天和几个饿了么的同学聊天,一听说他们还在用COLA 1.0 ,我二话没说,90 度鞠躬,赔礼道歉,虚心聆听他们的吐槽。COLA 的初衷旨在控制复杂度,救码农于水火,惭愧的是,早期的思想不成熟,设计也多有缺陷,不仅没帮到他们,反而坑了他们,实在抱歉。

实际上,我在COLA 3.0 迭代的时候,已经举起奥卡姆剃刀,砍掉了很多东西。

然而还不够,主要体现在对架构的思考还不够透彻。再三考量,我觉得有必要对COLA 进行一次重新梳理,回归初心, COLA真正成为应用架构的最佳实践,帮助广大的业务技术同学,脱离酱缸代码的泥潭!

应用架构的本质

什么是架构?十个人可能有十个回答,架构在技术的语境下,就和架构师一样魔幻。我曾经看过一本技术书,用了一章的篇幅讨论架构的定义,最终也没有说明白。

实际上,定义架构也没那么难,如下图所示,架构的本质,简单来说,就是 要素结构。所谓的 要素(Components)是指架构中的主要元素,结构是指要素之间的相互关系(Relationship

例如组织架构,其要素是什么?组成组织的要素当然是人,结构呢?结构是人与人之间的关系。因此,组织架构就是关于定义人的职责划分,以及人与人之间协作关系的一种设计方法。

同样,对于应用架构而言, 代码是其核心组成要素,结构就是这些代码该如何被组织,也就是要如何处理模块( Module )、组件(Component )、包(Package )和类(Class )之间的关系。简而言之, 应用架构就是要解决代码要如何被组织的问题。

一个没有架构的应用系统,就像一堆随意堆放、杂乱无章的玩具,只有熵值,没有熵减。而一个有良好架构的应用系统,有章法、有结构,一切都显得井井有条。

好的组织架构会遵循一定的架构模式,大部分的组织都会按职能和业务来设计自己的架构。如果你反其道而行之,硬要把销售、财务和技术人员放在一个部门,就会显得很奇怪。

同样,好的应用架构,也遵循一些共同模式,不管是六边形架构、洋葱圈架构、整洁架构、还是COLA 架构, 都提倡以业务为核心,解耦外部依赖,分离业务复杂度和技术复杂度

应用架构的本质,就是要从繁杂的业务系统中提炼出共性,找到解决业务问题的最佳共同模式,为开发人员提供统一的认知,治理混乱。帮助应用系统“ 从混乱到有序” ,COLA架构就是为此而生,其核心职责就是定义良好的应用结构,提供最佳实践

COLA 架构

自从COLA 诞生以来,已经被使用在很多的业务系统里面,有CRM 的业务,有电商的业务,有物流的业务,有外卖业务,有排课系统…. COLA 作为应用架构,有一定的普适性,是因为业务问题都有一定的共性。例如,典型的业务系统都需要:

· 接收request ,响应response ;

· 做业务逻辑处理,像校验参数,状态流转,业务计算等等;

· 和外部系统有联动,像数据库,微服务,搜索引擎等;

正是有这样的共性存在,才会有很多普适的架构思想出现,比如分层架构、六边形架构、洋葱圈架构、整洁架构(Clean Architecture )、DDD 架构等等。

这些应用架构思想虽然很好,但我们很多同学还是“ 不讲Co 德,明白了很多道理,可还是过不好这一生” 。问题就在于缺乏实践和指导。COLA 的意义就在于,他不仅是思想,还提供了可落地的实践。应该是为数不多的应用架构层面的开源软件。

分层结构

假如你是一个公司的CTO 要管100 号人,你怎么管?按照管理学的定义,一个人的管理幅度如果超过10 个,管理就会变得很困难。因此,管100 号人,你可以把他们分成10 个小组,这样你管理10 个小组长就好了。

所有的复杂系统都会呈现出层级结构,管理如此,软件设计也不例外,你能想象如果网络协议不是四层,而是一层,意味着,你要在应用层去处理链路层的bit 数据流会是怎样的情景吗?同样, 应用系统处理复杂业务逻辑也应该是分层的,下层对上层屏蔽处理细节,每一层各司其职,分离关注点,而不是一个ServiceImpl解决所有问题

对于一个典型的业务应用系统来说,COLA 会做如下层次定义,每一层都有明确的职责定义:

1 )适配层(Adapter Layer ):负责对前端展示(web ,wireless ,wap )的路由和适配,对于传统B/S 系统而言,adapter 就相当于MVC 中的controller ;

2 )应用层(Application Layer ):主要负责获取输入,组装上下文,参数校验,调用领域层做业务处理,如果需要的话,发送消息通知等。层次是开放的,应用层也可以绕过领域层,直接访问基础实施层;

3 )领域层(Domain Layer ):主要是封装了核心业务逻辑,并通过领域服务(Domain Service )和领域对象(Domain Entity )的方法对App 层提供业务实体和业务逻辑计算。领域是应用的核心,不依赖任何其他层次;

4 )基础实施层(Infrastructure Layer ):主要负责技术细节问题的处理,比如数据库的CRUD 、搜索引擎、文件系统、分布式服务的RPC 等。此外,领域防腐的重任也落在这里,外部依赖需要通过gateway 的转义处理,才能被上面的App 层和Domain 层使用。

包结构

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

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

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

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

层次

包名

功能

必选

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 。其中就包括 领域包的设计

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

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

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

解耦

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

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

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

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

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

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

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

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

这样做有两个好处,一个是降低了对外域信息依赖的耦合;另一个是通过上下文映射(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

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

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

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

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

作者简介:

阿里巴巴高级技术专家,张建飞。著有《代码精进之路:从码农到工匠》,凭借此书,获得2020年人民邮电出版社IT类最佳作者。是开源应用架构COLA的作者,擅长应用架构和领域建模。更多技术精华内容,请关注作者的微信公众号:从码农到工匠。

以分布式设计、架构、体系思想为基础,兼论研发相关的点点滴滴,不限于代码、质量体系和研发管理

(0)

相关推荐

  • 远卓:数字化转型的精益化思考

    内容摘要:以数字化驱动的业务转型战略为中心,制定组件化业务能力规划,以此建立敏捷/轻量的业务架构:在业务架构内将业务组件映射为子域,在子域内通过DDD设计应用架构,同时进一步修正业务架构. 建设数字中 ...

  • 领域驱动设计(DDD)理论与方法

    DDD由来与优势 软件架构设计的真正目的是解决软件复杂度带来的问题,软件复杂度由来主要由三方面:高并发场景下的对软件高性能要求.业务场景对软件高可用要求.持续变化的业务以及业务扩张和增加需求对软件扩展 ...

  • SpringCloud微服务开发实战:如何进行微服务的拆分?

    如何进行微服务的拆分 在前面介绍了基于Spring Boot来快速实现一个"天气预报"应用.虽然没有使用太多的代码,但已经实现了数据采集.数据缓存.提供天气查询等诸多的功能,这也是 ...

  • 使用 DDD 指导微服务拆分的逻辑

    对于服务拆分的逻辑来说,是先设计高内聚低耦合的领域模型,再实现相应的分布式系统.服务的划分有一些基本的方法和原则,通过这些方法能让微服务划分更有操作性.最终在微服务落地实施时也能按图索骥,无论是对遗留 ...

  • 为什么说应用架构需要分类思维?

    文末福利:有哪些个性有趣的域名? 模块(Module).组件(Component).包(Package),这些概念对于我们技术同学并不陌生,但并不是所有人都能理解其要义. 深入理解之后,我才发现,其背 ...

  • DDD之代码架构

    荒腔走板 这是一篇迟到的文章.这其实是我写DDD的第四篇文章.去年11月份左右我在个人网站上写了三篇关于DDD的文章,都是比较偏战略部分的.那个时候我还在一个正在使用DDD的项目上,也是我第一次真正开 ...

  • 阿里云技术专家:大型团队如何从0到1自建SRE体系

    凌云时刻 编者按:本文作者杨泽强(花名竹涧),弹性计算技术专家,14年加入阿里后先后从事DevOps以及SRE相关研发工作,目前在弹性计算负责SRE工程.本文根据作者在 GOPS2021 · 深圳站的 ...

  • (49条消息) 阿里技术专家详解DDD系列 第二弹

    阿里加多 2019-10-20 10:17:08 3936 收藏 8 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https:/ ...

  • 阿里 Mock 工具正式开源,干掉市面上所有 Mock 工具!

    TestableMock 简介 TestableMock 开源地址: https://github.com/alibaba/testable-mock TestableMock 在 2020 年 12 ...

  • 越军高级将领谈中越战争,称解放军使用新式武器,炮火猛烈

    1987年10月,越军副总参谋长阮世奔中将在<人民军队>杂志(这份刊物由越南国防部出版,供越军中高级干部阅读)第5期,发表了一篇关于越军作战情况以及训练改革的文章.这篇文章透露了越军总参谋 ...

  • “开源社区运营就像种菜”,黄东旭谈开源商业化 | 独家

    <CSDN编者按><程序员>于 2000 年创刊,其理念为技术改变世界,创新驱动中国.2021 年,全新的<程序员>2.0 重新起航,以专业的内容为立足点,以音视频 ...

  • 洪厚甜:从初级走向高级一一谈书法学习的路径

    我们为什么要设计篆书.隶书.行书.楷书这样一个课程呢?实际上就是让大家对篆书.隶书.行书.楷书这样整个书法技术的面有一个了解,中国书法的内容就是这些.这里面的内在逻辑联系是什么呢? 书法是从篆书开始的 ...

  • 浅谈开源组件与技术研发

    伴随着互联网的蓬勃发展,开源组件日益成为技术研发的重要工作基础.与商业化软件相比,开源软件生态的繁荣,为研发人员创造了一个"人人为我.我为人人"的自由环境. 从商业化研发组织而言, ...

  • 关于开源AI框架领域那些事

    关于开源AI框架领域那些事 2021年6月1日,北京智源人工智能研究院发布全球最大预训练模型-"悟道2.0"巨模型,参数量高达1.75万亿,比有1.6万亿个参数的谷歌最大模型Swi ...

  • 谈开源软件、开源许可证和逆向工程

    下学期准备一门新课,有一节内容是知识产权,重点讲开源软件和许可证.在收集材料过程中,我不仅找到很多有趣素材,更惊讶我们对开源许可证重视不够.对开源软件贡献微小.     自由软件(free softw ...