通过案例,实际着手拆分DDD
通过 漫谈DDD设计思想 我们初步了解了什么是DDD。DDD的思想,固然是好的,但落地较为繁琐,很多企业追求效率,敏捷开发,快速迭代,对DDD稍许有些看法,今天我们就通过案例梳理整个流程。一个好的DDD项目,应当如何产生,对开发又带来哪些好处。(一家之谈,不涉及细节)
DDD的核心,应该是技术区主动理解业务,所有的设计不能太过于超前,而是刚刚好解决问题。后面业务调整,相对的技术模块对应调整即可,不需要牵连全身。
背景
说白了,DDD其实就是给微服务做一个逻辑架构上面的指导,既然是涉及到微服务,但是划分微服务,就有很多讲究了。也有一些难点的:
微服务边界如何划分?
微服务的设计并非简单的应用拆分,而是需要更高效的实现‘高内聚、低耦合’,每个项目都有特殊性,每个项目都单独分析?能否有一个统一思想?
微服务设计如何坚守?
研发人员技术参差不齐,团队一般也不稳定,后期新入人员足够摧毁任何前期的优秀设计。
微服务项目如何推进?
每个项目的成本和团队情况都不一样,并不是所有项目都能够完整拥有业务、测试、开发、运维等等职能,如何保持一种统一的项目设计推进风格?
那,业界有没有一种统一的理论,或者统一的指导思想,把项目进行拆分呢?而不是每一个项目都需要各个造轮子的评审。这个方法论,是什么?
案例
我们通过设计一个 服务开发平台
的案例,使用DDD把整个流程串接起来。
比如你需要接入微信登录,你不能直接调用微信的接口吧,需要通过微信开发平台,录入你的信息,然后注册进来,开发平台给你分配秘钥,并且提供接口给你调用。你需要按照一定的格式、签名请求过来,开发平台给你响应等等功能。
由上可知,一个服务开发平台,需要拥有客户应用管理注册、请求转发、交易对账等核心功能。
事件风暴
通过事件风暴会议,构建初步领域模型。
DDD推崇的一种方式,事件风暴会议,基于工作坊的DDD实践方法,可以快速发现业务领域中正在发生的事件,指导领域建模及程序开发。
事件:即事实,即在业务领域中那些已经发生的事件就是事实。 风暴:运用头脑风暴会议进行领域分析建模。
特点:
功能很强大:能够在数小时而不是数周内提出完整业务流程的综合模型。
很有吸引力:整个想法是将提出问题并将知道答案的人带到同一房间,并共同建立一个模型。
容易:符号非常简单。
具体可以参考: 时间风暴会议流程
需要有以下环境、人员的参与。
主持人:产品经理
会议室:八米长的墙,足够大的空间,以及各种颜色的贴纸
参与方:业务需求方(产品)、领域专家、产品经理、项目经理、技术经理或者架构师。
得到的效果:通过时间风暴,建立领域模型,对子领域进行划分。确定子域的基本定位,并建立子域内核心概念的结构化模型,这将用来指导后续的微服务拆分。
比如服务开发平台,通过事件风暴,就可以得出三个领域:
- 一个是负责交易日志管理业务(HisRequest)
- 一个是负责核心的请求转发业务(GsService)
- 一个是负责客户端的管理业务(SysManage)
按照DDD指导的四层架构拆分
得出领域模型之后,就可以针对领域模型进行设计。我们需要有业务视角优先,我的领域划分了三个,那么在代码设计上,也应该按照三个领域进行拆包结构。当然领域不限于包结构的表达方式,可以是一个子项目、子模块等等,不过一般我们都是一个package。
语言统一,我们分了package之后,那包里面的业务层次如何定义,我们需要按照固定的方式,定义出来四层架构。这样便于构建统一的语言描述各个组件的作用。 当然,四层架构是参考,而不是限制,只要项目内形成统一即可。
比如以下:
- entity:领域的当中的实体
- infrastructure:基础设施层
- repository:仓库层
- service:领域服务层
每个领域,都是这几层架构,这就是通用语言的一种表达方式。也就是理解了一个领域模块的设计,其他所有的领域跟着来就好了,不需要重复造轮子了。
哎呀,是不是还多了一层 adaptor? 这其实是领域和领域之间的合作协调,领域之间通过adaptor层的接口形成依赖,也就是限界上下文,通过adaptor形成业务能力的纵向切分,一般来说,我们都是通过接口进行实现。
也就是,如果要访问领域内的功能,只能通过限界上下文的接口来访问。这就是一个简单的框架。
这像不像,微服务?都是通过接口进行调用,然后实现接口下,去实现业务。
至于这几层如何实现,就不具体展开了,各个概念模块,可看上篇文章。
没错,后续如果转微服务,直接把包拆分出去即可。修改非常小。
基于DDD的单体架构优势
基于DDD的架构设计除的单体架构版本,具有:
业务优先
软件架构与业务领域涉及保持一致,业务如何运行,架构就如何设计,最大程度防止技术与业务脱节
领域驱动
各个领域分工明确,职责清洗,而各领域内部,也保留了灵活的扩展空间
接入灵活
后端服务只需要提供基于SDK即可,平台本身不需要做调整
成本可控
可单机部署,没有外部依赖,快速进行业务验证,架构调整灵活
领域涉及是由业务驱动的,快速落地,快速验证,刚刚好的支撑业务。
基于DDD的微服务架构
架构灵活
单体架构往微服务架构调整,改动量较少
接入方便
后端服务由多个可选的接入方案,接入平台更为灵活
设计更精准
当前架构下,微服务拆分是业务精准驱动,资源投入更精确,也更合理
按需拆分、按需投入,好的架构从来都是演进出来的,而不是设计出来的。
后续
我们新起来一个项目,初期不能估算其规模,如果按照一上来就MVC,后续规模大了无法拆分,我们在前面也讲到了。如果一上来就上微服务,你也很难估算他的各个模块拆分。
正确的做法,应该是在单体模式下,按照DDD的设计来划分各个业务模块,各个领域,领域与领域之间的分解等等。如果在单体下面你都划分不出来,更别谈什么微服务划分了。 等到某块业务,单体支撑不下,就可以随时把整个领取单独拎出来,升级成微服务,改动量是比较少的,也快速迭代上线,不要老是想着重构。